feat: 支持账单编辑(PATCH /api/bills/:id)

This commit is contained in:
clz
2026-01-18 20:17:19 +08:00
parent 339b8afe98
commit f5afb0c135
8 changed files with 326 additions and 37 deletions

View File

@@ -0,0 +1,6 @@
package repository
import "errors"
// ErrNotFound 表示目标记录不存在
var ErrNotFound = errors.New("not found")

View File

@@ -7,6 +7,7 @@ import (
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
@@ -383,6 +384,40 @@ func (r *Repository) GetMonthlyStats() ([]model.MonthlyStat, error) {
return stats, nil
}
// UpdateCleanedBillByID 按 ID 更新清洗后的账单,并返回更新后的记录
func (r *Repository) UpdateCleanedBillByID(id string, updates map[string]interface{}) (*model.CleanedBill, error) {
if r.cleanedCollection == nil {
return nil, fmt.Errorf("cleaned collection not initialized")
}
oid, err := primitive.ObjectIDFromHex(id)
if err != nil {
return nil, fmt.Errorf("invalid id: %w", err)
}
if len(updates) == 0 {
return nil, fmt.Errorf("no updates")
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
filter := bson.M{"_id": oid}
update := bson.M{"$set": updates}
opts := options.FindOneAndUpdate().SetReturnDocument(options.After)
var updated model.CleanedBill
err = r.cleanedCollection.FindOneAndUpdate(ctx, filter, update, opts).Decode(&updated)
if err != nil {
if err == mongo.ErrNoDocuments {
return nil, repository.ErrNotFound
}
return nil, fmt.Errorf("update bill failed: %w", err)
}
return &updated, nil
}
// GetClient 获取 MongoDB 客户端(用于兼容旧代码)
func (r *Repository) GetClient() *mongo.Client {
return r.client

View File

@@ -43,6 +43,9 @@ type BillRepository interface {
// GetBillsNeedReview 获取需要复核的账单
GetBillsNeedReview() ([]model.CleanedBill, error)
// UpdateCleanedBillByID 按 ID 更新清洗后的账单,并返回更新后的记录
UpdateCleanedBillByID(id string, updates map[string]interface{}) (*model.CleanedBill, error)
// CountRawByField 按字段统计原始数据数量
CountRawByField(fieldName, value string) (int64, error)
}