package repository import ( "context" "errors" "time" "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity" "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository" mgo "code.30cm.net/digimon/library-go/mongo" "github.com/zeromicro/go-zero/core/stores/cache" "github.com/zeromicro/go-zero/core/stores/mon" "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" ) type KYCRepositoryParam struct { Conf *mgo.Conf CacheConf cache.CacheConf DBOpts []mon.Option CacheOpts []cache.Option } type KYCRepository struct { DB mgo.DocumentDBWithCacheUseCase } func NewKYCRepository(param KYCRepositoryParam) repository.KYCRepository { e := entity.KYC{} documentDB, err := mgo.MustDocumentDBWithCache( param.Conf, e.CollectionName(), param.CacheConf, param.DBOpts, param.CacheOpts, ) if err != nil { panic(err) } return &KYCRepository{ DB: documentDB, } } func (repo *KYCRepository) Create(ctx context.Context, data *entity.KYC) error { if data.ID.IsZero() { now := time.Now().UTC().UnixNano() data.ID = primitive.NewObjectID() data.CreatedAt = now data.UpdatedAt = now } _, err := repo.DB.GetClient().InsertOne(ctx, data) return err } func (repo *KYCRepository) FindLatestByUID(ctx context.Context, uid string) (*entity.KYC, error) { filter := bson.M{"uid": uid} var result entity.KYC opts := options.FindOne().SetSort(bson.D{{Key: "created_at", Value: -1}}) // 用 SetSort 加入排序 err := repo.DB.GetClient().FindOne(ctx, &result, filter, opts) if err != nil { if errors.Is(err, mongo.ErrNoDocuments) { return nil, ErrNotFound } return nil, err } return &result, nil } func (repo *KYCRepository) FindByID(ctx context.Context, id string) (*entity.KYC, error) { oid, err := primitive.ObjectIDFromHex(id) if err != nil { return nil, err } filter := bson.M{"_id": oid} var result entity.KYC err = repo.DB.GetClient().FindOne(ctx, &result, filter) if err != nil { return nil, err } return &result, nil } func (repo *KYCRepository) List(ctx context.Context, params repository.KYCQueryParams) ([]*entity.KYC, int64, error) { filter := bson.M{} if params.UID != nil { filter["uid"] = *params.UID } if params.Country != nil { filter["country_region"] = *params.Country } if params.Status != nil { filter["status"] = *params.Status } // 設置排序選項 opts := options.Find().SetSkip((params.PageIndex - 1) * params.PageSize).SetLimit(params.PageSize) //if params.SortByDate { // opts.SetSort(bson.E{Key: "created_at", Value: -1}) //} else { // opts.SetSort(bson.D{{Key: "updated_at", Value: -1}}) //} // 查詢符合條件的總數 total, err := repo.DB.GetClient().CountDocuments(ctx, filter) if err != nil { return nil, 0, err } // 執行查詢並獲取結果 var results []*entity.KYC err = repo.DB.GetClient().Find(ctx, &results, filter, opts) if err != nil { return nil, 0, err } return results, total, nil } func (repo *KYCRepository) UpdateStatus(ctx context.Context, id string, status string, reason string) error { oid, err := primitive.ObjectIDFromHex(id) if err != nil { return err } filter := bson.M{"_id": oid} update := bson.M{ "$set": bson.M{ "status": status, "reject_reason": reason, "updated_at": time.Now().UTC().UnixNano(), }, } _, err = repo.DB.GetClient().UpdateOne(ctx, filter, update) return err } func (repo *KYCRepository) UpdateKYCInfo(ctx context.Context, id string, update *repository.KYCUpdateParams) error { oid, err := primitive.ObjectIDFromHex(id) if err != nil { return err } setFields := bson.M{"updated_at": time.Now().UTC().UnixNano()} if update.Name != nil { setFields["name"] = *update.Name } if update.Identification != nil { setFields["identification"] = *update.Identification } if update.IdentificationType != nil { setFields["identification_type"] = *update.IdentificationType } if update.Address != nil { setFields["address"] = *update.Address } if update.PostalCode != nil { setFields["postal_code"] = *update.PostalCode } if update.IDFrontImage != nil { setFields["id_front_image"] = *update.IDFrontImage } if update.IDBackImage != nil { setFields["id_back_image"] = *update.IDBackImage } if update.BankStatementImg != nil { setFields["bank_statement_img"] = *update.BankStatementImg } if update.BankCode != nil { setFields["bank_code"] = *update.BankCode } if update.BankName != nil { setFields["bank_name"] = *update.BankName } if update.BranchCode != nil { setFields["branch_code"] = *update.BranchCode } if update.BranchName != nil { setFields["branch_name"] = *update.BranchName } if update.BankAccount != nil { setFields["bank_account"] = *update.BankAccount } filter := bson.M{"_id": oid, "status": "PENDING"} // 僅允許更新尚未審核的 updateDoc := bson.M{"$set": setFields} _, err = repo.DB.GetClient().UpdateOne(ctx, filter, updateDoc) return err }