package usecase import ( "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity" "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository" "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/usecase" "code.30cm.net/digimon/app-cloudep-product-service/pkg/utils" "context" "github.com/zeromicro/go-zero/core/logx" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readconcern" "code.30cm.net/digimon/library-go/errs" "code.30cm.net/digimon/library-go/errs/code" ) type ProductUseCaseParam struct { ProductRepo repository.ProductRepository TagRepo repository.TagRepo TagBinding repository.TagBindingRepo ProductStatisticsRepo repository.ProductStatisticsRepo } type ProductUseCase struct { ProductUseCaseParam } func MustProductUseCase(param ProductUseCaseParam) usecase.ProductUseCase { return &ProductUseCase{ param, } } func (use *ProductUseCase) Create(ctx context.Context, product *usecase.Product) error { // 資料前處理:準備 entity.Product 實體 insert := &entity.Product{} if product.UID != nil { insert.UID = *product.UID } if product.Title != nil { insert.Title = *product.Title } if product.IsPublished != nil { insert.IsPublished = *product.IsPublished } if product.Category != nil { insert.Category = *product.Category } if product.ShortTitle != nil { insert.ShortTitle = product.ShortTitle } if product.Details != nil { insert.Details = product.Details } if product.ShortDescription != nil { insert.ShortDescription = *product.ShortDescription } if product.Slug != nil { insert.Slug = product.Slug } if product.Amount != 0 { insert.Amount = product.Amount } if product.StartTime != nil { st := utils.Rfc3339ToUnix(utils.ToValue(product.StartTime)) insert.StartTime = &st } if product.EndTime != nil { et := utils.Rfc3339ToUnix(utils.ToValue(product.EndTime)) insert.EndTime = &et } if len(product.Media) > 0 { medias := make([]entity.Media, 0, len(product.Media)) for _, m := range product.Media { medias = append(medias, entity.Media{ Sort: m.Sort, URL: m.URL, Type: m.Type, }) } insert.Media = medias } if len(product.CustomFields) > 0 { cf := make([]entity.CustomFields, 0, len(product.CustomFields)) for _, field := range product.CustomFields { cf = append(cf, entity.CustomFields{ Key: field.Key, Value: field.Value, }) } insert.CustomFields = cf } // Transaction 設定:只做必要寫入 opts := options.Transaction().SetReadConcern(readconcern.Local()) err := use.ProductRepo.Transaction(ctx, func(sessCtx mongo.SessionContext) (any, error) { // 插入 Product if err := use.ProductRepo.Insert(sessCtx, insert); err != nil { e := errs.DBError(code.CloudEPProduct, 0) return nil, err } // 插入 Product 統計資料 if err := use.ProductStatisticsRepo.Create(sessCtx, &entity.ProductStatistics{ ProductID: insert.ID.Hex(), Orders: 0, OrdersUpdateTime: 0, AverageRating: 0, AverageRatingUpdateTime: 0, FansCount: 0, FansCountUpdateTime: 0, }); err != nil { return nil, err } // 過濾 Tag // 綁定 Tags for _, tag := range product.Tags { if err := use.TagBinding.BindTag(sessCtx, &entity.TagsBindingTable{ ReferenceID: insert.ID.Hex(), TagID: tag, }); err != nil { logx.Errorf("failed to bind tag %s to product %s: %v", tag, insert.ID.Hex(), err) return nil, err } } return nil, nil }, opts) if err != nil { return err } return nil } func (use *ProductUseCase) Update(ctx context.Context, id string, product *usecase.Product) error { //TODO implement me panic("implement me") } func (use *ProductUseCase) Delete(ctx context.Context, id string) error { //TODO implement me panic("implement me") } func (use *ProductUseCase) Get(ctx context.Context, id string) (*usecase.ProductResp, error) { //TODO implement me panic("implement me") } func (use *ProductUseCase) List(ctx context.Context, data usecase.ProductQueryParams) ([]*usecase.ProductResp, int64, error) { //TODO implement me panic("implement me") } func (use *ProductUseCase) IncOrders(ctx context.Context, productID string, count int64) error { //TODO implement me panic("implement me") } func (use *ProductUseCase) DecOrders(ctx context.Context, productID string, count int64) error { //TODO implement me panic("implement me") } func (use *ProductUseCase) UpdateAverageRating(ctx context.Context, productID string, averageRating float64) error { //TODO implement me panic("implement me") } func (use *ProductUseCase) IncFansCount(ctx context.Context, productID string, fansCount uint64) error { //TODO implement me panic("implement me") } func (use *ProductUseCase) DecFansCount(ctx context.Context, productID string, fansCount uint64) error { //TODO implement me panic("implement me") } func (use *ProductUseCase) BindTag(ctx context.Context, binding usecase.TagsBindingTable) error { //TODO implement me panic("implement me") } func (use *ProductUseCase) UnbindTag(ctx context.Context, binding usecase.TagsBindingTable) error { //TODO implement me panic("implement me") } func (use *ProductUseCase) GetBindingsByReference(ctx context.Context, referenceID string) ([]usecase.TagsBindingTableResp, error) { //TODO implement me panic("implement me") } func (use *ProductUseCase) ListTagBinding(ctx context.Context, params usecase.TagBindingQueryParams) ([]usecase.TagsBindingTableResp, int64, error) { //TODO implement me panic("implement me") }