package model import ( "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/bsontype" "go.mongodb.org/mongo-driver/bson/primitive" ) // LocalTime 自定义时间类型,JSON 序列化时输出本地时间格式 type LocalTime time.Time // MarshalJSON 实现 json.Marshaler 接口,输出本地时间格式 func (t LocalTime) MarshalJSON() ([]byte, error) { tt := time.Time(t) if tt.IsZero() { return []byte(`""`), nil } // 输出格式: "2006-01-02 15:04:05" return []byte(`"` + tt.Local().Format("2006-01-02 15:04:05") + `"`), nil } // UnmarshalJSON 实现 json.Unmarshaler 接口 func (t *LocalTime) UnmarshalJSON(data []byte) error { s := string(data) if s == `""` || s == "null" { *t = LocalTime(time.Time{}) return nil } // 去掉引号 s = s[1 : len(s)-1] // 尝试多种格式解析 formats := []string{ "2006-01-02 15:04:05", "2006-01-02T15:04:05Z07:00", "2006-01-02T15:04:05Z", "2006-01-02", } for _, format := range formats { if parsed, err := time.ParseInLocation(format, s, time.Local); err == nil { *t = LocalTime(parsed) return nil } } return nil } // MarshalBSONValue 实现 bson.ValueMarshaler 接口 func (t LocalTime) MarshalBSONValue() (bsontype.Type, []byte, error) { return bson.MarshalValue(time.Time(t)) } // UnmarshalBSONValue 实现 bson.ValueUnmarshaler 接口 func (t *LocalTime) UnmarshalBSONValue(btype bsontype.Type, data []byte) error { var tt time.Time if err := bson.UnmarshalValue(btype, data, &tt); err != nil { return err } *t = LocalTime(tt) return nil } // Time 返回标准 time.Time func (t LocalTime) Time() time.Time { return time.Time(t) } // RawBill 原始账单记录(存储上传的原始数据) type RawBill struct { ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"` 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"` // 原始行号 RawData map[string]interface{} `bson:"raw_data" json:"raw_data"` // 原始字段数据 CreatedAt time.Time `bson:"created_at" json:"created_at"` // 创建时间 } // CleanedBill 清洗后账单记录(标准化后的数据) type CleanedBill struct { ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"` 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"` // 交易时间(本地时间格式) Category string `bson:"category" json:"category"` // 交易分类 Merchant string `bson:"merchant" json:"merchant"` // 交易对方 Description string `bson:"description" json:"description"` // 商品说明 IncomeExpense string `bson:"income_expense" json:"income_expense"` // 收/支 Amount float64 `bson:"amount" json:"amount"` // 金额 PayMethod string `bson:"pay_method" json:"pay_method"` // 支付方式 Status string `bson:"status" json:"status"` // 交易状态 Remark string `bson:"remark" json:"remark"` // 备注 ReviewLevel string `bson:"review_level" json:"review_level"` // 复核等级: HIGH/LOW/空 IsDeleted bool `bson:"is_deleted" json:"is_deleted"` // 是否已删除(软删除) CreatedAt time.Time `bson:"created_at" json:"created_at"` // 创建时间 UpdatedAt time.Time `bson:"updated_at" json:"updated_at"` // 更新时间 SourceFile string `bson:"source_file" json:"source_file"` // 来源文件名 UploadBatch string `bson:"upload_batch" json:"upload_batch"` // 上传批次(时间戳) } // MonthlyStat 月度统计数据 type MonthlyStat struct { Month string `bson:"month" json:"month"` // 月份 YYYY-MM Expense float64 `bson:"expense" json:"expense"` // 月支出总额 Income float64 `bson:"income" json:"income"` // 月收入总额 }