feat: 支持京东白条账单上传和清洗
This commit is contained in:
@@ -13,14 +13,14 @@ type CleanOptions struct {
|
||||
|
||||
// CleanResult 清洗结果
|
||||
type CleanResult struct {
|
||||
BillType string // 检测到的账单类型: alipay/wechat
|
||||
BillType string // 检测到的账单类型: alipay/wechat/jd
|
||||
Output string // 脚本输出信息
|
||||
}
|
||||
|
||||
// ConvertResult 格式转换结果
|
||||
type ConvertResult struct {
|
||||
OutputPath string // 转换后的文件路径
|
||||
BillType string // 检测到的账单类型: alipay/wechat
|
||||
BillType string // 检测到的账单类型: alipay/wechat/jd
|
||||
}
|
||||
|
||||
// Cleaner 账单清洗器接口
|
||||
|
||||
@@ -87,6 +87,9 @@ func detectBillTypeFromOutput(output string) string {
|
||||
if strings.Contains(output, "微信") {
|
||||
return "wechat"
|
||||
}
|
||||
if strings.Contains(output, "京东") {
|
||||
return "jd"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ type ListBillsRequest struct {
|
||||
StartDate string `form:"start_date"` // 开始日期 YYYY-MM-DD
|
||||
EndDate string `form:"end_date"` // 结束日期 YYYY-MM-DD
|
||||
Category string `form:"category"` // 分类筛选
|
||||
Type string `form:"type"` // 账单类型 alipay/wechat
|
||||
Type string `form:"type"` // 账单类型 alipay/wechat/jd
|
||||
IncomeExpense string `form:"income_expense"` // 收支类型 收入/支出
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,8 @@ func Upload(c *gin.Context) {
|
||||
billType = "alipay"
|
||||
} else if strings.Contains(fileName, "微信") || strings.Contains(fileName, "wechat") {
|
||||
billType = "wechat"
|
||||
} else if strings.Contains(fileName, "京东") || strings.Contains(fileName, "jd") {
|
||||
billType = "jd"
|
||||
}
|
||||
}
|
||||
if billType == "" {
|
||||
@@ -152,15 +154,15 @@ func Upload(c *gin.Context) {
|
||||
service.CleanupExtractedFiles(extractedFiles)
|
||||
c.JSON(http.StatusBadRequest, model.UploadResponse{
|
||||
Result: false,
|
||||
Message: "无法识别账单类型,请指定 type 参数 (alipay 或 wechat)",
|
||||
Message: "无法识别账单类型,请指定 type 参数 (alipay/wechat/jd)",
|
||||
})
|
||||
return
|
||||
}
|
||||
if billType != "alipay" && billType != "wechat" {
|
||||
if billType != "alipay" && billType != "wechat" && billType != "jd" {
|
||||
service.CleanupExtractedFiles(extractedFiles)
|
||||
c.JSON(http.StatusBadRequest, model.UploadResponse{
|
||||
Result: false,
|
||||
Message: "账单类型无效,仅支持 alipay 或 wechat",
|
||||
Message: "账单类型无效,仅支持 alipay/wechat/jd",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ func (t LocalTime) Time() time.Time {
|
||||
// RawBill 原始账单记录(存储上传的原始数据)
|
||||
type RawBill struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
|
||||
BillType string `bson:"bill_type" json:"bill_type"` // 账单类型: alipay/wechat
|
||||
BillType string `bson:"bill_type" json:"bill_type"` // 账单类型: alipay/wechat/jd
|
||||
SourceFile string `bson:"source_file" json:"source_file"` // 来源文件名
|
||||
UploadBatch string `bson:"upload_batch" json:"upload_batch"` // 上传批次(时间戳)
|
||||
RowIndex int `bson:"row_index" json:"row_index"` // 原始行号
|
||||
@@ -81,7 +81,7 @@ type RawBill struct {
|
||||
// CleanedBill 清洗后账单记录(标准化后的数据)
|
||||
type CleanedBill struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
|
||||
BillType string `bson:"bill_type" json:"bill_type"` // 账单类型: alipay/wechat
|
||||
BillType string `bson:"bill_type" json:"bill_type"` // 账单类型: alipay/wechat/jd
|
||||
TransactionID string `bson:"transaction_id" json:"transaction_id"` // 交易订单号(用于去重)
|
||||
MerchantOrderNo string `bson:"merchant_order_no" json:"merchant_order_no"` // 商家订单号(用于去重)
|
||||
Time LocalTime `bson:"time" json:"time"` // 交易时间(本地时间格式)
|
||||
|
||||
@@ -2,7 +2,7 @@ package model
|
||||
|
||||
// UploadRequest 上传请求参数
|
||||
type UploadRequest struct {
|
||||
Type string `form:"type"` // 账单类型: alipay/wechat(可选,会自动检测)
|
||||
Type string `form:"type"` // 账单类型: alipay/wechat/jd(可选,会自动检测)
|
||||
Password string `form:"password"` // ZIP 文件密码(可选)
|
||||
Year string `form:"year"` // 年份筛选
|
||||
Month string `form:"month"` // 月份筛选
|
||||
|
||||
@@ -2,7 +2,7 @@ package model
|
||||
|
||||
// UploadData 上传响应数据
|
||||
type UploadData struct {
|
||||
BillType string `json:"bill_type,omitempty"` // alipay/wechat
|
||||
BillType string `json:"bill_type,omitempty"` // alipay/wechat/jd
|
||||
FileURL string `json:"file_url,omitempty"` // 下载链接
|
||||
FileName string `json:"file_name,omitempty"` // 文件名
|
||||
RawCount int `json:"raw_count,omitempty"` // 存储到原始数据集合的记录数
|
||||
|
||||
@@ -105,6 +105,8 @@ func ExtractZip(zipPath, destDir, password string) (*ExtractResult, error) {
|
||||
result.BillType = "alipay"
|
||||
} else if strings.Contains(fileName, "微信") || strings.Contains(strings.ToLower(fileName), "wechat") {
|
||||
result.BillType = "wechat"
|
||||
} else if strings.Contains(fileName, "京东") || strings.Contains(strings.ToLower(fileName), "jd") {
|
||||
result.BillType = "jd"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +150,10 @@ func detectBillTypeAndIdField(header []string) (billType string, idFieldIdx int)
|
||||
if col == "交易类型" || col == "金额(元)" {
|
||||
billType = "wechat"
|
||||
}
|
||||
// 京东特征
|
||||
if col == "商户名称" || col == "交易说明" {
|
||||
billType = "jd"
|
||||
}
|
||||
|
||||
// 查找去重字段(优先使用交易订单号/交易号)
|
||||
if col == "交易订单号" || col == "交易号" || col == "交易单号" {
|
||||
|
||||
@@ -36,6 +36,9 @@ func DetectBillTypeFromOutput(output string) string {
|
||||
if containsSubstring(output, "微信") {
|
||||
return "wechat"
|
||||
}
|
||||
if containsSubstring(output, "京东") {
|
||||
return "jd"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user