fix(web, server): 修复数据分析页面总支出和大盘数据错误
- 数据分析页面改为使用后端返回的聚合统计,而不是前端计算 - 移除后端 page_size 最大 100 的限制,允许获取更多数据 - 确保账单管理和数据分析页面使用相同的数据源,保证一致性 - 更新版本号至 1.0.6
This commit is contained in:
@@ -5,6 +5,14 @@
|
|||||||
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),
|
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),
|
||||||
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
||||||
|
|
||||||
|
## [1.0.6] - 2026-01-08
|
||||||
|
|
||||||
|
### 修复
|
||||||
|
- **数据分析页面总支出和大盘数据错误** - 修复数据分析页面与账单管理页面总支出不一致的问题
|
||||||
|
- 原因:后端限制 `page_size` 最大为 100,但前端请求了 10000,导致只获取到部分数据
|
||||||
|
- 解决:数据分析页面改为使用后端返回的聚合统计(`total_expense`),而不是前端计算,且关闭后端最大100的限制
|
||||||
|
- 现在两个页面都使用相同的后端数据库聚合统计,确保数据一致性
|
||||||
|
|
||||||
## [1.0.5] - 2026-01-08
|
## [1.0.5] - 2026-01-08
|
||||||
|
|
||||||
### 优化
|
### 优化
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
一个基于微服务架构的个人账单分析工具,支持微信和支付宝账单的自动解析、智能分类和可视化分析。
|
一个基于微服务架构的个人账单分析工具,支持微信和支付宝账单的自动解析、智能分类和可视化分析。
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
@@ -273,6 +273,7 @@ python server.py
|
|||||||
|
|
||||||
| 版本 | 日期 | 主要更新 |
|
| 版本 | 日期 | 主要更新 |
|
||||||
|------|------|----------|
|
|------|------|----------|
|
||||||
|
| **v1.0.6** | 2026-01-08 | 🐛 修复数据分析页面总支出和大盘数据错误 |
|
||||||
| **v1.0.5** | 2026-01-08 | 🐛 修复支付宝时间格式解析错误,修复WebHook编译错误 |
|
| **v1.0.5** | 2026-01-08 | 🐛 修复支付宝时间格式解析错误,修复WebHook编译错误 |
|
||||||
| **v1.0.4** | 2026-01-13 | 🚀 Gitea Webhook 自动部署、零停机热更新 |
|
| **v1.0.4** | 2026-01-13 | 🚀 Gitea Webhook 自动部署、零停机热更新 |
|
||||||
| **v1.0.3** | 2026-01-13 | ✨ DateTimePicker 组件、收支分类动态切换 |
|
| **v1.0.3** | 2026-01-13 | ✨ DateTimePicker 组件、收支分类动态切换 |
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# BillAI 服务器配置文件
|
# BillAI 服务器配置文件
|
||||||
|
|
||||||
# 应用版本
|
# 应用版本
|
||||||
version: "1.0.5"
|
version: "1.0.6"
|
||||||
|
|
||||||
# 服务配置
|
# 服务配置
|
||||||
server:
|
server:
|
||||||
|
|||||||
@@ -58,9 +58,9 @@ func ListBills(c *gin.Context) {
|
|||||||
if req.PageSize < 1 {
|
if req.PageSize < 1 {
|
||||||
req.PageSize = 20
|
req.PageSize = 20
|
||||||
}
|
}
|
||||||
if req.PageSize > 100 {
|
// if req.PageSize > 100 {
|
||||||
req.PageSize = 100 // 限制最大每页数量
|
// req.PageSize = 100 // 限制最大每页数量
|
||||||
}
|
// }
|
||||||
|
|
||||||
// 构建筛选条件
|
// 构建筛选条件
|
||||||
filter := make(map[string]interface{})
|
filter := make(map[string]interface{})
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
import AlertCircle from '@lucide/svelte/icons/alert-circle';
|
import AlertCircle from '@lucide/svelte/icons/alert-circle';
|
||||||
import Activity from '@lucide/svelte/icons/activity';
|
import Activity from '@lucide/svelte/icons/activity';
|
||||||
import RefreshCw from '@lucide/svelte/icons/refresh-cw';
|
import RefreshCw from '@lucide/svelte/icons/refresh-cw';
|
||||||
import Calendar from '@lucide/svelte/icons/calendar';
|
|
||||||
|
|
||||||
// 分析组件
|
// 分析组件
|
||||||
import {
|
import {
|
||||||
@@ -58,6 +57,10 @@
|
|||||||
let isDemo = $state(false);
|
let isDemo = $state(false);
|
||||||
let serverAvailable = $state(true);
|
let serverAvailable = $state(true);
|
||||||
|
|
||||||
|
// 后端返回的聚合统计(准确的总支出/收入)
|
||||||
|
let backendTotalExpense = $state(0);
|
||||||
|
let backendTotalIncome = $state(0);
|
||||||
|
|
||||||
// 日期范围筛选 - 初始化为默认值
|
// 日期范围筛选 - 初始化为默认值
|
||||||
let startYear = $state(defaultDates.startYear);
|
let startYear = $state(defaultDates.startYear);
|
||||||
let startMonth = $state(defaultDates.startMonth);
|
let startMonth = $state(defaultDates.startMonth);
|
||||||
@@ -92,7 +95,14 @@
|
|||||||
let allAnalysisRecords = $derived(isDemo ? demoRecords : toAnalysisRecords(allRecords)); // 全部数据用于每日趋势图
|
let allAnalysisRecords = $derived(isDemo ? demoRecords : toAnalysisRecords(allRecords)); // 全部数据用于每日趋势图
|
||||||
let categoryStats = $derived(calculateCategoryStats(analysisRecords));
|
let categoryStats = $derived(calculateCategoryStats(analysisRecords));
|
||||||
let dailyExpenseData = $derived(calculateDailyExpenseData(analysisRecords));
|
let dailyExpenseData = $derived(calculateDailyExpenseData(analysisRecords));
|
||||||
let totalStats = $derived(calculateTotalStats(analysisRecords));
|
|
||||||
|
// 使用后端返回的聚合统计(准确),如果没有则使用前端计算(作为后备)
|
||||||
|
let totalStats = $derived({
|
||||||
|
expense: backendTotalExpense > 0 ? backendTotalExpense : calculateTotalStats(analysisRecords).expense,
|
||||||
|
income: backendTotalIncome > 0 ? backendTotalIncome : calculateTotalStats(analysisRecords).income,
|
||||||
|
count: analysisRecords.length,
|
||||||
|
});
|
||||||
|
|
||||||
let pieChartData = $derived(calculatePieChartData(categoryStats, totalStats.expense));
|
let pieChartData = $derived(calculatePieChartData(categoryStats, totalStats.expense));
|
||||||
let topExpenses = $derived(getTopExpenses(analysisRecords, 10));
|
let topExpenses = $derived(getTopExpenses(analysisRecords, 10));
|
||||||
|
|
||||||
@@ -138,6 +148,9 @@
|
|||||||
// 处理账单数据
|
// 处理账单数据
|
||||||
if (billsResponse.result && billsResponse.data) {
|
if (billsResponse.result && billsResponse.data) {
|
||||||
records = billsResponse.data.bills || [];
|
records = billsResponse.data.bills || [];
|
||||||
|
// 使用后端返回的聚合统计(准确的总支出/收入)
|
||||||
|
backendTotalExpense = billsResponse.data.total_expense || 0;
|
||||||
|
backendTotalIncome = billsResponse.data.total_income || 0;
|
||||||
if (records.length === 0) {
|
if (records.length === 0) {
|
||||||
errorMessage = '暂无账单数据';
|
errorMessage = '暂无账单数据';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user