package logic import ( "context" "errors" "juwan-backend/app/shop/rpc/internal/models/predicate" "juwan-backend/app/shop/rpc/internal/models/shops" "time" "juwan-backend/app/shop/rpc/internal/svc" "juwan-backend/app/shop/rpc/pb" "encoding/json" "github.com/shopspring/decimal" "github.com/zeromicro/go-zero/core/logx" ) type SearchShopsLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } func NewSearchShopsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SearchShopsLogic { return &SearchShopsLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } func (l *SearchShopsLogic) SearchShops(in *pb.SearchShopsReq) (*pb.SearchShopsResp, error) { if in.Limit <= 0 { in.Limit = 20 } if in.Limit > 1000 { return nil, errors.New("limit too large") } preds := make([]predicate.Shops, 0, 12) if in.Id > 0 { preds = append(preds, shops.IDEQ(in.Id)) } if in.OwnerId > 0 { preds = append(preds, shops.OwnerIDEQ(in.OwnerId)) } if in.Name != "" { preds = append(preds, shops.NameContainsFold(in.Name)) } if in.Description != "" { preds = append(preds, shops.DescriptionContainsFold(in.Description)) } if in.CommissionType != "" { preds = append(preds, shops.CommissionTypeEQ(in.CommissionType)) } if in.DispatchMode != "" { preds = append(preds, shops.DispatchModeEQ(in.DispatchMode)) } if in.Rating != "" { rating, perr := decimal.NewFromString(in.Rating) if perr != nil { return nil, errors.New("invalid rating") } preds = append(preds, shops.RatingGTE(rating)) } if in.CommissionValue != "" { commissionValue, perr := decimal.NewFromString(in.CommissionValue) if perr != nil { return nil, errors.New("invalid commissionValue") } preds = append(preds, shops.CommissionValueGTE(commissionValue)) } if in.TotalOrders > 0 { preds = append(preds, shops.TotalOrdersGTE(int(in.TotalOrders))) } if in.PlayerCount > 0 { preds = append(preds, shops.PlayerCountGTE(int(in.PlayerCount))) } if in.AllowMultiShop { preds = append(preds, shops.AllowMultiShopEQ(true)) } if in.AllowIndependentOrders { preds = append(preds, shops.AllowIndependentOrdersEQ(true)) } if in.CreatedAt > 0 { preds = append(preds, shops.CreatedAtGTE(time.Unix(in.CreatedAt, 0))) } if in.UpdatedAt > 0 { preds = append(preds, shops.UpdatedAtGTE(time.Unix(in.UpdatedAt, 0))) } query := l.svcCtx.ShopModelRO.Shops.Query() if len(preds) > 0 { query = query.Where(shops.And(preds...)) } list, err := query. Offset(int(in.Offset)). Limit(int(in.Limit)). All(l.ctx) if err != nil { logx.Errorf("search shops failed, %s", err.Error()) return nil, errors.New("search shops failed") } result := make([]*pb.Shops, 0, len(list)) for _, item := range list { templateConfigBytes, err := json.Marshal(item.TemplateConfig) if err != nil { logx.WithContext(l.ctx).Errorf("marshal template config failed: %v", err) continue } pbItem := &pb.Shops{ Id: item.ID, OwnerId: item.OwnerID, Name: item.Name, Rating: item.Rating.String(), TotalOrders: int64(item.TotalOrders), PlayerCount: int64(item.PlayerCount), CommissionType: item.CommissionType, CommissionValue: item.CommissionValue.String(), AllowMultiShop: item.AllowMultiShop, AllowIndependentOrders: item.AllowIndependentOrders, DispatchMode: item.DispatchMode, Announcements: item.Announcements.Elements, TemplateConfig: string(templateConfigBytes), CreatedAt: item.CreatedAt.Unix(), UpdatedAt: item.UpdatedAt.Unix(), } if item.Banner != nil { pbItem.Banner = *item.Banner } if item.Description != nil { pbItem.Description = *item.Description } result = append(result, pbItem) } return &pb.SearchShopsResp{Shops: result}, nil }