2025-03-21 09:12:08 +00:00
package usecase
import (
2025-04-06 02:08:46 +00:00
"context"
"errors"
2025-03-21 09:12:08 +00:00
"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"
2025-03-31 13:24:40 +00:00
repo "code.30cm.net/digimon/app-cloudep-product-service/pkg/repository"
2025-03-23 16:08:32 +00:00
"code.30cm.net/digimon/app-cloudep-product-service/pkg/utils"
2025-03-25 07:58:02 +00:00
"code.30cm.net/digimon/library-go/errs"
2025-03-23 16:08:32 +00:00
"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"
2025-03-21 09:12:08 +00:00
)
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 {
2025-03-31 13:24:40 +00:00
insert := convertUseCaseToEntity ( product )
2025-03-23 16:08:32 +00:00
// Transaction 設定:只做必要寫入
opts := options . Transaction ( ) . SetReadConcern ( readconcern . Local ( ) )
2025-04-06 02:08:46 +00:00
//nolint:contextcheck
2025-03-23 16:08:32 +00:00
err := use . ProductRepo . Transaction ( ctx , func ( sessCtx mongo . SessionContext ) ( any , error ) {
if err := use . ProductRepo . Insert ( sessCtx , insert ) ; err != nil {
2025-03-31 13:24:40 +00:00
return nil , logDBError ( ctx , "ProductRepo.Insert" , [ ] logx . LogField { { Key : "req" , Value : product } } , err , "failed to create product" )
2025-03-23 16:08:32 +00:00
}
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 {
2025-03-31 13:24:40 +00:00
return nil , logDBError ( ctx , "ProductStatisticsRepo.Create" , [ ] logx . LogField { { Key : "ProductID" , Value : insert . ID . Hex ( ) } } , err , "failed to create product statistics" )
2025-03-23 16:08:32 +00:00
}
2025-03-31 13:24:40 +00:00
tagsBinding := buildTagsBinding ( insert . ID . Hex ( ) , product . Tags )
2025-03-25 09:28:05 +00:00
if err := use . TagBinding . BindTags ( sessCtx , tagsBinding ) ; err != nil {
2025-03-31 13:24:40 +00:00
return nil , logDBError ( ctx , "TagBinding.BindTags" , [ ] logx . LogField { { Key : "ReferenceID" , Value : insert . ID . Hex ( ) } , { Key : "tags" , Value : product . Tags } } , err , "failed to bind product tags" )
2025-03-25 09:28:05 +00:00
}
2025-03-23 16:08:32 +00:00
2025-04-06 02:08:46 +00:00
return struct { } { } , nil
2025-03-23 16:08:32 +00:00
} , opts )
2025-03-21 09:12:08 +00:00
if err != nil {
return err
}
2025-03-23 16:08:32 +00:00
return nil
2025-03-21 09:12:08 +00:00
}
func ( use * ProductUseCase ) Update ( ctx context . Context , id string , product * usecase . Product ) error {
2025-03-31 13:24:40 +00:00
update := convertUseCaseToUpdateParams ( product )
tagsBinding := buildTagsBinding ( id , product . Tags )
2025-03-25 09:28:05 +00:00
opts := options . Transaction ( ) . SetReadConcern ( readconcern . Local ( ) )
err := use . ProductRepo . Transaction ( ctx , func ( sessCtx mongo . SessionContext ) ( any , error ) {
2025-04-06 02:08:46 +00:00
//nolint:contextcheck
2025-03-25 09:28:05 +00:00
_ , err := use . ProductRepo . Update ( sessCtx , id , update )
if err != nil {
2025-03-31 13:24:40 +00:00
return nil , logDBError ( ctx , "ProductRepo.Update" , [ ] logx . LogField { { Key : "req" , Value : product } } , err , "failed to update product" )
2025-03-25 09:28:05 +00:00
}
2025-04-06 02:08:46 +00:00
//nolint:contextcheck
2025-03-25 09:28:05 +00:00
if err := use . TagBinding . UnbindTagByReferenceID ( sessCtx , id ) ; err != nil {
2025-03-31 13:24:40 +00:00
return nil , logDBError ( ctx , "TagBinding.UnbindTagByReferenceID" , [ ] logx . LogField { { Key : "ReferenceID" , Value : id } } , err , "failed to unbind tags" )
2025-03-25 09:28:05 +00:00
}
2025-04-06 02:08:46 +00:00
//nolint:contextcheck
2025-03-25 09:28:05 +00:00
if err := use . TagBinding . BindTags ( sessCtx , tagsBinding ) ; err != nil {
2025-03-31 13:24:40 +00:00
return nil , logDBError ( ctx , "TagBinding.BindTags" , [ ] logx . LogField { { Key : "ReferenceID" , Value : id } , { Key : "tags" , Value : product . Tags } } , err , "failed to bind tags" )
2025-03-25 09:28:05 +00:00
}
2025-04-06 02:08:46 +00:00
return struct { } { } , nil
2025-03-25 09:28:05 +00:00
} , opts )
2025-03-31 13:24:40 +00:00
return err
2025-03-21 09:12:08 +00:00
}
func ( use * ProductUseCase ) Delete ( ctx context . Context , id string ) error {
2025-03-25 09:28:05 +00:00
// Transaction 設定:只做必要寫入
opts := options . Transaction ( ) . SetReadConcern ( readconcern . Local ( ) )
err := use . ProductRepo . Transaction ( ctx , func ( sessCtx mongo . SessionContext ) ( any , error ) {
2025-04-06 02:08:46 +00:00
//nolint:contextcheck
2025-03-25 09:28:05 +00:00
err := use . ProductRepo . Delete ( sessCtx , id )
if err != nil {
e := errs . DBErrorL ( logx . WithContext ( ctx ) ,
[ ] logx . LogField {
{ Key : "ReferenceID" , Value : id } ,
{ Key : "func" , Value : "ProductRepo.Delete" } ,
{ Key : "err" , Value : err . Error ( ) } ,
} , "failed to delete product" )
return nil , e
}
2025-04-06 02:08:46 +00:00
//nolint:contextcheck
2025-03-25 09:28:05 +00:00
err = use . TagRepo . UnbindTagByReferenceID ( sessCtx , id )
if err != nil {
e := errs . DBErrorL ( logx . WithContext ( ctx ) ,
[ ] logx . LogField {
{ Key : "ReferenceID" , Value : id } ,
{ Key : "func" , Value : "TagBinding.UnbindTagByReferenceID" } ,
{ Key : "err" , Value : err . Error ( ) } ,
} , "failed to unbind tags" )
return nil , e
}
2025-04-06 02:08:46 +00:00
return struct { } { } , nil
2025-03-25 09:28:05 +00:00
} , opts )
if err != nil {
return err
}
return nil
2025-03-21 09:12:08 +00:00
}
func ( use * ProductUseCase ) Get ( ctx context . Context , id string ) ( * usecase . ProductResp , error ) {
2025-03-25 09:28:05 +00:00
product , err := use . ProductRepo . FindOneByID ( ctx , id )
if err != nil {
2025-03-31 13:24:40 +00:00
return nil , logDBError ( ctx , "ProductRepo.FindOneByID" , [ ] logx . LogField { { Key : "product_id" , Value : id } } , err , "failed to find product" )
2025-03-25 09:28:05 +00:00
}
2025-03-31 13:24:40 +00:00
stats , err := use . ProductStatisticsRepo . GetByID ( ctx , id )
2025-03-25 09:28:05 +00:00
if err != nil {
2025-03-31 13:24:40 +00:00
return nil , logDBError ( ctx , "ProductStatisticsRepo.GetByID" , [ ] logx . LogField { { Key : "product_id" , Value : id } } , err , "failed to get product statistics" )
2025-03-25 09:28:05 +00:00
}
2025-03-31 13:24:40 +00:00
bindings , err := use . TagRepo . GetBindingsByReference ( ctx , id )
2025-03-25 09:28:05 +00:00
if err != nil {
2025-03-31 13:24:40 +00:00
return nil , logDBError ( ctx , "TagRepo.GetBindingsByReference" , [ ] logx . LogField { { Key : "product_id" , Value : id } } , err , "failed to get tag bindings" )
2025-03-25 09:28:05 +00:00
}
2025-03-31 13:24:40 +00:00
tagIDs := make ( [ ] string , 0 , len ( bindings ) )
for _ , item := range bindings {
tagIDs = append ( tagIDs , item . TagID )
2025-03-25 09:28:05 +00:00
}
2025-03-31 13:24:40 +00:00
tags , err := use . TagRepo . GetByIDs ( ctx , tagIDs )
2025-03-25 09:28:05 +00:00
if err != nil {
2025-03-31 13:24:40 +00:00
return nil , logDBError ( ctx , "TagRepo.GetByIDs" , [ ] logx . LogField { { Key : "product_id" , Value : id } } , err , "failed to get tags" )
2025-03-25 09:28:05 +00:00
}
2025-03-31 13:24:40 +00:00
return convertEntityToResp ( product , stats , tags ) , nil
2025-03-21 09:12:08 +00:00
}
2025-03-31 13:24:40 +00:00
// TODO 效能有問題這邊優先改, List 會有N + 1 問題
2025-03-21 09:12:08 +00:00
func ( use * ProductUseCase ) List ( ctx context . Context , data usecase . ProductQueryParams ) ( [ ] * usecase . ProductResp , int64 , error ) {
2025-03-25 09:28:05 +00:00
query := & repository . ProductQueryParams {
PageSize : data . PageSize ,
PageIndex : data . PageIndex ,
}
if data . Slug != nil {
query . Slug = data . Slug
}
if data . UID != nil {
query . UID = data . UID
}
if data . IsPublished != nil {
query . IsPublished = data . IsPublished
}
if data . Category != nil {
query . Category = data . Category
}
if data . StartTime != nil {
query . StartTime = data . StartTime
}
2025-03-31 13:24:40 +00:00
if data . EndTime != nil {
query . EndTime = data . EndTime
}
2025-03-25 09:28:05 +00:00
2025-03-31 13:24:40 +00:00
products , total , err := use . ProductRepo . ListProduct ( ctx , query )
2025-03-25 09:28:05 +00:00
if err != nil {
return nil , 0 , err
}
2025-03-31 13:24:40 +00:00
result := make ( [ ] * usecase . ProductResp , 0 , len ( products ) )
for _ , p := range products {
// 查詢統計資料
stats , _ := use . ProductStatisticsRepo . GetByID ( ctx , p . ID . Hex ( ) )
// 查詢 Tag 資訊
tags , _ := use . TagRepo . GetBindingsByReference ( ctx , p . ID . Hex ( ) )
tagIDs := make ( [ ] string , 0 , len ( tags ) )
for _ , t := range tags {
tagIDs = append ( tagIDs , t . TagID )
}
tagsInfo , _ := use . TagRepo . GetByIDs ( ctx , tagIDs )
// 組合 Tags 回應
respTags := make ( [ ] usecase . Tags , 0 , len ( tagsInfo ) )
for _ , tag := range tagsInfo {
item := usecase . Tags {
ID : tag . ID . Hex ( ) ,
Types : tag . Types ,
Name : tag . Name ,
ShowType : tag . ShowType ,
UpdatedAt : utils . UnixToRfc3339 ( tag . UpdatedAt ) ,
CreatedAt : utils . UnixToRfc3339 ( tag . CreatedAt ) ,
}
if tag . Cover != nil {
item . Cover = * tag . Cover
}
respTags = append ( respTags , item )
}
// Media & CustomFields
media := make ( [ ] usecase . Media , 0 , len ( p . Media ) )
for _ , m := range p . Media {
media = append ( media , usecase . Media {
Sort : m . Sort ,
URL : m . URL ,
Type : m . Type ,
} )
}
customFields := make ( [ ] usecase . CustomFields , 0 , len ( p . CustomFields ) )
for _ , f := range p . CustomFields {
customFields = append ( customFields , usecase . CustomFields {
Key : f . Key ,
Value : f . Value ,
} )
}
resp := & usecase . ProductResp {
ID : p . ID . Hex ( ) ,
UID : p . UID ,
Title : p . Title ,
ShortTitle : utils . ToValue ( p . ShortTitle ) ,
Details : utils . ToValue ( p . Details ) ,
ShortDescription : p . ShortDescription ,
Media : media ,
Slug : utils . ToValue ( p . Slug ) ,
IsPublished : p . IsPublished ,
Amount : p . Amount ,
StartTime : utils . UnixToRfc3339 ( utils . ToValue ( p . StartTime ) ) ,
EndTime : utils . UnixToRfc3339 ( utils . ToValue ( p . EndTime ) ) ,
Category : p . Category ,
CustomFields : customFields ,
Tags : respTags ,
Orders : stats . Orders ,
OrdersUpdateTime : utils . UnixToRfc3339 ( stats . OrdersUpdateTime ) ,
AverageRating : stats . AverageRating ,
AverageRatingUpdateTime : utils . UnixToRfc3339 ( stats . AverageRatingUpdateTime ) ,
FansCount : stats . FansCount ,
FansCountUpdateTime : utils . UnixToRfc3339 ( stats . FansCountUpdateTime ) ,
UpdatedAt : utils . UnixToRfc3339 ( p . UpdatedAt ) ,
CreatedAt : utils . UnixToRfc3339 ( p . CreatedAt ) ,
}
result = append ( result , resp )
}
return result , total , nil
2025-03-21 09:12:08 +00:00
}
func ( use * ProductUseCase ) IncOrders ( ctx context . Context , productID string , count int64 ) error {
2025-03-31 13:24:40 +00:00
err := use . ProductStatisticsRepo . IncOrders ( ctx , productID , count )
if err != nil {
return errs . DBErrorL ( logx . WithContext ( ctx ) ,
[ ] logx . LogField {
{ Key : "product_id" , Value : productID } ,
{ Key : "func" , Value : "ProductStatisticsRepo.IncOrders" } ,
{ Key : "err" , Value : err . Error ( ) } ,
} , "failed to inc order" )
}
return nil
2025-03-21 09:12:08 +00:00
}
func ( use * ProductUseCase ) DecOrders ( ctx context . Context , productID string , count int64 ) error {
2025-03-31 13:24:40 +00:00
err := use . ProductStatisticsRepo . DecOrders ( ctx , productID , count )
if err != nil {
return errs . DBErrorL ( logx . WithContext ( ctx ) ,
[ ] logx . LogField {
{ Key : "product_id" , Value : productID } ,
{ Key : "func" , Value : "ProductStatisticsRepo.DecOrders" } ,
{ Key : "err" , Value : err . Error ( ) } ,
} , "failed to dec order" )
}
return nil
2025-03-21 09:12:08 +00:00
}
func ( use * ProductUseCase ) UpdateAverageRating ( ctx context . Context , productID string , averageRating float64 ) error {
2025-03-31 13:24:40 +00:00
err := use . ProductStatisticsRepo . UpdateAverageRating ( ctx , productID , averageRating )
if err != nil {
return errs . DBErrorL ( logx . WithContext ( ctx ) ,
[ ] logx . LogField {
{ Key : "product_id" , Value : productID } ,
{ Key : "func" , Value : "ProductStatisticsRepo.UpdateAverageRating" } ,
{ Key : "err" , Value : err . Error ( ) } ,
} , "failed to update average rating" )
}
return nil
2025-03-21 09:12:08 +00:00
}
func ( use * ProductUseCase ) IncFansCount ( ctx context . Context , productID string , fansCount uint64 ) error {
2025-03-31 13:24:40 +00:00
err := use . ProductStatisticsRepo . IncFansCount ( ctx , productID , fansCount )
if err != nil {
return errs . DBErrorL ( logx . WithContext ( ctx ) ,
[ ] logx . LogField {
{ Key : "product_id" , Value : productID } ,
{ Key : "func" , Value : "ProductStatisticsRepo.IncFansCount" } ,
{ Key : "err" , Value : err . Error ( ) } ,
} , "failed to inc fans count" )
}
return nil
2025-03-21 09:12:08 +00:00
}
func ( use * ProductUseCase ) DecFansCount ( ctx context . Context , productID string , fansCount uint64 ) error {
2025-03-31 13:24:40 +00:00
err := use . ProductStatisticsRepo . DecFansCount ( ctx , productID , fansCount )
if err != nil {
return errs . DBErrorL ( logx . WithContext ( ctx ) ,
[ ] logx . LogField {
{ Key : "product_id" , Value : productID } ,
{ Key : "func" , Value : "ProductStatisticsRepo.DecFansCount" } ,
{ Key : "err" , Value : err . Error ( ) } ,
} , "failed to dec fans count" )
}
return nil
2025-03-21 09:12:08 +00:00
}
func ( use * ProductUseCase ) BindTag ( ctx context . Context , binding usecase . TagsBindingTable ) error {
2025-03-31 13:24:40 +00:00
_ , err := use . TagRepo . GetByID ( ctx , binding . TagID )
if err != nil {
if errors . Is ( err , repo . ErrNotFound ) {
return errs . ResourceNotFound ( "failed to get tags" )
}
return err
}
_ , err = use . ProductRepo . FindOneByID ( ctx , binding . ReferenceID )
if err != nil {
if errors . Is ( err , repo . ErrNotFound ) {
return errs . ResourceNotFound ( "failed to get tags" )
}
return err
}
err = use . TagBinding . BindTags ( ctx , [ ] * entity . TagsBindingTable { { ReferenceID : binding . ReferenceID , TagID : binding . TagID } } )
if err != nil {
return errs . DBErrorL ( logx . WithContext ( ctx ) ,
[ ] logx . LogField {
{ Key : "binding" , Value : binding } ,
{ Key : "func" , Value : "TagBinding.BindTags" } ,
{ Key : "err" , Value : err . Error ( ) } ,
} , "failed to bind tags" )
}
return nil
2025-03-21 09:12:08 +00:00
}
func ( use * ProductUseCase ) UnbindTag ( ctx context . Context , binding usecase . TagsBindingTable ) error {
2025-03-31 13:24:40 +00:00
_ , err := use . TagRepo . GetByID ( ctx , binding . TagID )
if err != nil {
if errors . Is ( err , repo . ErrNotFound ) {
return errs . ResourceNotFound ( "failed to get tags" )
}
return err
}
_ , err = use . ProductRepo . FindOneByID ( ctx , binding . ReferenceID )
if err != nil {
if errors . Is ( err , repo . ErrNotFound ) {
return errs . ResourceNotFound ( "failed to get tags" )
}
return err
}
err = use . TagBinding . UnbindTag ( ctx , binding . TagID , binding . ReferenceID )
if err != nil {
return errs . DBErrorL ( logx . WithContext ( ctx ) ,
[ ] logx . LogField {
{ Key : "binding" , Value : binding } ,
{ Key : "func" , Value : "TagBinding.UnbindTag" } ,
{ Key : "err" , Value : err . Error ( ) } ,
} , "failed to unbind tags" )
}
return nil
2025-03-21 09:12:08 +00:00
}
func ( use * ProductUseCase ) GetBindingsByReference ( ctx context . Context , referenceID string ) ( [ ] usecase . TagsBindingTableResp , error ) {
2025-03-31 13:24:40 +00:00
ref , err := use . TagBinding . GetBindingsByReference ( ctx , referenceID )
if err != nil {
return nil , errs . DBErrorL ( logx . WithContext ( ctx ) ,
[ ] logx . LogField {
{ Key : "referenceID" , Value : referenceID } ,
{ Key : "func" , Value : "TagBinding.GetBindingsByReference" } ,
{ Key : "err" , Value : err . Error ( ) } ,
} , "failed to get bindings by reference" )
}
result := make ( [ ] usecase . TagsBindingTableResp , 0 , len ( ref ) )
for _ , bind := range ref {
result = append ( result , usecase . TagsBindingTableResp {
ID : bind . ID . Hex ( ) ,
ReferenceID : bind . ReferenceID ,
TagID : bind . TagID ,
CreatedAt : utils . UnixToRfc3339 ( bind . CreatedAt ) ,
UpdatedAt : utils . UnixToRfc3339 ( bind . UpdatedAt ) ,
} )
}
return result , nil
2025-03-21 09:12:08 +00:00
}
func ( use * ProductUseCase ) ListTagBinding ( ctx context . Context , params usecase . TagBindingQueryParams ) ( [ ] usecase . TagsBindingTableResp , int64 , error ) {
2025-03-31 13:24:40 +00:00
ref , total , err := use . TagBinding . ListTagBinding ( ctx , repository . TagBindingQueryParams {
ReferenceID : params . ReferenceID ,
TagID : params . TagID ,
PageIndex : params . PageIndex ,
PageSize : params . PageSize ,
} )
if err != nil {
return nil , 0 , errs . DBErrorL ( logx . WithContext ( ctx ) ,
[ ] logx . LogField {
{ Key : "params" , Value : params } ,
{ Key : "func" , Value : "TagBinding.ListTagBinding" } ,
{ Key : "err" , Value : err . Error ( ) } ,
} , "failed to list tags" )
}
result := make ( [ ] usecase . TagsBindingTableResp , 0 , len ( ref ) )
for _ , bind := range ref {
result = append ( result , usecase . TagsBindingTableResp {
ID : bind . ID . Hex ( ) ,
ReferenceID : bind . ReferenceID ,
TagID : bind . TagID ,
CreatedAt : utils . UnixToRfc3339 ( bind . CreatedAt ) ,
UpdatedAt : utils . UnixToRfc3339 ( bind . UpdatedAt ) ,
} )
}
return result , total , nil
}
func logDBError ( ctx context . Context , funcName string , fields [ ] logx . LogField , err error , msg string ) error {
return errs . DBErrorL ( logx . WithContext ( ctx ) , append ( fields , logx . Field ( "func" , funcName ) , logx . Field ( "err" , err . Error ( ) ) ) , msg )
}
func buildTagsBinding ( referenceID string , tags [ ] string ) [ ] * entity . TagsBindingTable {
binding := make ( [ ] * entity . TagsBindingTable , 0 , len ( tags ) )
for _ , tag := range tags {
binding = append ( binding , & entity . TagsBindingTable {
ReferenceID : referenceID ,
TagID : tag ,
} )
}
2025-04-06 02:08:46 +00:00
2025-03-31 13:24:40 +00:00
return binding
}
func convertUseCaseToEntity ( product * usecase . Product ) * 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
}
return insert
}
func convertUseCaseToUpdateParams ( product * usecase . Product ) * repository . ProductUpdateParams {
update := & repository . ProductUpdateParams { }
if product . Title != nil {
update . Title = product . Title
}
if product . IsPublished != nil {
update . IsPublished = product . IsPublished
}
if product . Category != nil {
update . Category = product . Category
}
if product . ShortTitle != nil {
update . ShortTitle = product . ShortTitle
}
if product . Details != nil {
update . Details = product . Details
}
if product . ShortDescription != nil {
update . ShortDescription = * product . ShortDescription
}
if product . Slug != nil {
update . Slug = product . Slug
}
if product . Amount != 0 {
update . Amount = & product . Amount
}
if product . StartTime != nil {
st := utils . Rfc3339ToUnix ( utils . ToValue ( product . StartTime ) )
update . StartTime = & st
}
if product . EndTime != nil {
et := utils . Rfc3339ToUnix ( utils . ToValue ( product . EndTime ) )
update . 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 } )
}
update . 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 } )
}
update . CustomFields = cf
}
2025-04-06 02:08:46 +00:00
2025-03-31 13:24:40 +00:00
return update
}
func convertEntityToResp ( p * entity . Product , stats * entity . ProductStatistics , tags [ ] * entity . Tags ) * usecase . ProductResp {
tagsResp := make ( [ ] usecase . Tags , 0 , len ( tags ) )
for _ , tag := range tags {
item := usecase . Tags {
ID : tag . ID . Hex ( ) ,
Types : tag . Types ,
Name : tag . Name ,
ShowType : tag . ShowType ,
UpdatedAt : utils . UnixToRfc3339 ( tag . UpdatedAt ) ,
CreatedAt : utils . UnixToRfc3339 ( tag . CreatedAt ) ,
}
if tag . Cover != nil {
item . Cover = * tag . Cover
}
tagsResp = append ( tagsResp , item )
}
media := make ( [ ] usecase . Media , 0 , len ( p . Media ) )
for _ , m := range p . Media {
media = append ( media , usecase . Media { Sort : m . Sort , URL : m . URL , Type : m . Type } )
}
cf := make ( [ ] usecase . CustomFields , 0 , len ( p . CustomFields ) )
for _ , field := range p . CustomFields {
cf = append ( cf , usecase . CustomFields { Key : field . Key , Value : field . Value } )
}
return & usecase . ProductResp {
ID : p . ID . Hex ( ) ,
UID : p . UID ,
Title : p . Title ,
ShortTitle : utils . ToValue ( p . ShortTitle ) ,
Details : utils . ToValue ( p . Details ) ,
ShortDescription : p . ShortDescription ,
Slug : utils . ToValue ( p . Slug ) ,
IsPublished : p . IsPublished ,
Amount : p . Amount ,
StartTime : utils . UnixToRfc3339 ( utils . ToValue ( p . StartTime ) ) ,
EndTime : utils . UnixToRfc3339 ( utils . ToValue ( p . EndTime ) ) ,
Category : p . Category ,
Media : media ,
CustomFields : cf ,
Tags : tagsResp ,
Orders : stats . Orders ,
OrdersUpdateTime : utils . UnixToRfc3339 ( stats . OrdersUpdateTime ) ,
AverageRating : stats . AverageRating ,
AverageRatingUpdateTime : utils . UnixToRfc3339 ( stats . AverageRatingUpdateTime ) ,
FansCount : stats . FansCount ,
FansCountUpdateTime : utils . UnixToRfc3339 ( stats . FansCountUpdateTime ) ,
UpdatedAt : utils . UnixToRfc3339 ( p . UpdatedAt ) ,
CreatedAt : utils . UnixToRfc3339 ( p . CreatedAt ) ,
}
2025-03-21 09:12:08 +00:00
}