fix(server, webhook): 添加 MongoDB 数据持久化和上传前去重功能

- 优化支付宝时间格式解析(支持无前导零格式)
- 修复 webhook 服务编译错误
- 更新版本号至 1.0.5
This commit is contained in:
CHE LIANG ZHAO
2026-01-14 14:53:50 +08:00
parent 05ab270677
commit 4805f94126
6 changed files with 50 additions and 4 deletions

1
.gitignore vendored
View File

@@ -21,5 +21,6 @@ server/billai-server
server/uploads/
server/outputs/
*.log
*.exe
mongodata/

View File

@@ -5,6 +5,14 @@
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/)
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
## [1.0.5] - 2026-01-08
### 优化
- **支付宝时间格式解析** - 支持无前导零的日期格式
- 自动标准化 `2026/1/13 20:08``2026/01/13 20:08`
- 兼容支付宝账单的时间格式
- **Webhook 服务修复** - 移除未使用的 `fmt` 导入,修复编译错误
## [1.0.4] - 2026-01-13
### 新增

View File

@@ -2,7 +2,7 @@
一个基于微服务架构的个人账单分析工具,支持微信和支付宝账单的自动解析、智能分类和可视化分析。
![版本](https://img.shields.io/badge/版本-1.0.4-green)
![版本](https://img.shields.io/badge/版本-1.0.5-green)
![架构](https://img.shields.io/badge/架构-微服务-blue)
![Go](https://img.shields.io/badge/Go-1.21-00ADD8)
![Python](https://img.shields.io/badge/Python-3.12-3776AB)
@@ -16,6 +16,7 @@
- 🏷️ **智能分类** - 基于关键词匹配的交易分类推断
- 📈 **趋势图表** - 日/月消费趋势、分类排行、收支对比
- 🔍 **复核修正** - 对不确定的分类进行人工复核
- 💾 **数据持久化** - MongoDB 存储原始数据和清洗后数据,支持去重检查
- 🐳 **一键部署** - Docker Compose 快速启动全部服务
- 🚀 **自动部署** - Gitea Webhook 触发零停机热更新
@@ -67,9 +68,11 @@ sequenceDiagram
Note over U,D: 上传账单流程
U->>W: 上传账单文件
W->>S: POST /api/upload
S->>D: 去重检查(原始数据集合)
D-->>S: 重复记录数
S->>A: POST /clean (清洗账单)
A-->>S: 清洗结果 + 分类
S->>D: 存储账单数据
S->>D: 存储原始数据 + 清洗后数据
D-->>S: 保存成功
S-->>W: 返回分析结果
W-->>U: 显示分析报表
@@ -228,6 +231,8 @@ python server.py
| `ANALYZER_MODE` | `http` | 适配器模式: http/subprocess |
| `MONGO_URI` | `mongodb://localhost:27017` | MongoDB 连接 URI |
| `MONGO_DATABASE` | `billai` | 数据库名称 |
| `MONGO_RAW_COLLECTION` | `bills_raw` | 原始数据集合名称 |
| `MONGO_CLEANED_COLLECTION` | `bills_cleaned` | 清洗后数据集合名称 |
| `JWT_SECRET` | - | JWT 加密密钥 |
| `TOKEN_EXPIRY` | `24` | Token 过期时间(小时) |
| `ADMIN_USERNAME` | - | 管理员用户名(可选) |
@@ -268,6 +273,7 @@ python server.py
| 版本 | 日期 | 主要更新 |
|------|------|----------|
| **v1.0.5** | 2026-01-08 | 🐛 修复支付宝时间格式解析错误修复WebHook编译错误 |
| **v1.0.4** | 2026-01-13 | 🚀 Gitea Webhook 自动部署、零停机热更新 |
| **v1.0.3** | 2026-01-13 | ✨ DateTimePicker 组件、收支分类动态切换 |
| **v1.0.2** | 2026-01-11 | 🐛 修复时区和金额解析问题 |

View File

@@ -1,7 +1,7 @@
# BillAI 服务器配置文件
# 应用版本
version: "1.0.2"
version: "1.0.5"
# 服务配置
server:

View File

@@ -490,12 +490,44 @@ func saveCleanedBillsFromJSON(filePath, billType, sourceFile, uploadBatch string
// parseTime 解析时间字符串
// 使用本地时区解析,返回 model.LocalTime 类型
// 支持支付宝格式: 2026/1/13 20:08 (月份和日期可能没有前导零)
func parseTime(s string) model.LocalTime {
s = strings.TrimSpace(s)
if s == "" {
return model.LocalTime(time.Time{})
}
// 先尝试标准化支付宝格式(将单数日期/月份补零)
// 例如: "2026/1/13 20:08" -> "2026/01/13 20:08"
if strings.Contains(s, "/") && !strings.Contains(s, "-") {
// 匹配格式: YYYY/M/D 或 YYYY/M/D HH:mm 或 YYYY/M/D HH:mm:ss
parts := strings.Split(s, " ")
if len(parts) > 0 {
datePart := parts[0]
// 使用正则表达式将单数日期/月份补零
// 例如: "2026/1/13" -> "2026/01/13"
dateParts := strings.Split(datePart, "/")
if len(dateParts) == 3 {
year := dateParts[0]
month := dateParts[1]
day := dateParts[2]
// 补零
if len(month) == 1 {
month = "0" + month
}
if len(day) == 1 {
day = "0" + day
}
datePart = year + "/" + month + "/" + day
if len(parts) > 1 {
s = datePart + " " + strings.Join(parts[1:], " ")
} else {
s = datePart
}
}
}
}
// 尝试多种时间格式(使用本地时区)
formats := []string{
"2006-01-02 15:04:05",

View File

@@ -6,7 +6,6 @@ import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"log"
"net/http"