diff --git a/model/gmodel/fs_product_collection_logic.go b/model/gmodel/fs_product_collection_logic.go index 1db33376..cd513830 100644 --- a/model/gmodel/fs_product_collection_logic.go +++ b/model/gmodel/fs_product_collection_logic.go @@ -35,3 +35,18 @@ func (c *FsProductCollectionModel) Delete2(ctx context.Context, userId, guestId, Where("user_id = ? and guest_id = ? and id = ?", userId, guestId, id). Delete(&FsProductCollection{}).Error } + +// 获取列表 +func (c *FsProductCollectionModel) GetList(ctx context.Context, userId, guestId int64, page, limit int, sort string) (resp []FsProductCollection, total int64, err error) { + db := c.db.WithContext(ctx).Model(&FsProductCollection{}). + Where("user_id = ? and guest_id = ?", userId, guestId) + if sort != "" { + db = db.Order(sort) + } + if err = db.Count(&total).Error; err != nil { + return nil, 0, err + } + offset := (page - 1) * limit + err = db.Offset(offset).Limit(limit).Find(&resp).Error + return resp, total, err +} diff --git a/server/collection/internal/logic/collectproductlogic.go b/server/collection/internal/logic/collectproductlogic.go index c006d877..9fc27cf4 100644 --- a/server/collection/internal/logic/collectproductlogic.go +++ b/server/collection/internal/logic/collectproductlogic.go @@ -36,10 +36,10 @@ func NewCollectProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Co func (l *CollectProductLogic) CollectProduct(req *types.CollectProductReq, userinfo *auth.UserInfo) (resp *basic.Response) { if !userinfo.IsUser() && !userinfo.IsGuest() { - return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in before to collect product") + return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in before collect product") } //查询产品 - productInfo, err := l.svcCtx.AllModels.FsProduct.FindOne(l.ctx, req.ProductId, "id,is_shelf") + productInfo, err := l.svcCtx.AllModels.FsProduct.FindOne(l.ctx, req.ProductId) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the product is not found") @@ -48,9 +48,9 @@ func (l *CollectProductLogic) CollectProduct(req *types.CollectProductReq, useri return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "faile to get product info") } //校验下状态 - if *productInfo.Status != 1 { + /*if *productInfo.Status != 1 { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "the product status is unNormal") - } + }*/ //下架了 if *productInfo.IsShelf == 0 { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "the product is off shelf") @@ -81,9 +81,9 @@ func (l *CollectProductLogic) CollectProduct(req *types.CollectProductReq, useri logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to collect product") } - return resp.SetStatus(basic.CodeOK) + return resp.SetStatusWithMessage(basic.CodeOK, "The product has been collected successfully") } - return resp.SetStatusAddMessage(basic.CodeOK, "you have collect this product and don`t need to repeat again") + return resp.SetStatusAddMessage(basic.CodeOK, "You have collect this product and don`t need to repeat again") } // 处理逻辑后 w,r 如:重定向, resp 必须重新处理 diff --git a/server/collection/internal/logic/getcollectproductlistlogic.go b/server/collection/internal/logic/getcollectproductlistlogic.go index ca91aef1..d7c71a2a 100644 --- a/server/collection/internal/logic/getcollectproductlistlogic.go +++ b/server/collection/internal/logic/getcollectproductlistlogic.go @@ -1,8 +1,15 @@ package logic import ( + "encoding/json" + "fmt" + "fusenapi/constants" + "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" + "fusenapi/utils/format" + "fusenapi/utils/s3url_to_s3id" + "math" "context" @@ -31,10 +38,150 @@ func NewGetCollectProductListLogic(ctx context.Context, svcCtx *svc.ServiceConte // } func (l *GetCollectProductListLogic) GetCollectProductList(req *types.GetCollectProductListReq, userinfo *auth.UserInfo) (resp *basic.Response) { - // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) - // userinfo 传入值时, 一定不为null - - return resp.SetStatus(basic.CodeOK) + if req.CurrentPage <= 0 { + req.CurrentPage = constants.DEFAULT_PAGE + } + limit := 10 + //查询列表 + collectionList, total, err := l.svcCtx.AllModels.FsProductCollection.GetList(l.ctx, userinfo.UserId, userinfo.GuestId, req.CurrentPage, limit, "id DESC") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get collection list") + } + //没有数据 + if len(collectionList) == 0 { + return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetCollectProductListRsp{ + Meta: types.Meta{ + TotalCount: total, + PageCount: int64(math.Ceil(float64(total) / float64(limit))), + CurrentPage: req.CurrentPage, + PerPage: limit, + }, + List: []types.GetCollectProductListRspItem{}, + }) + } + productIds := make([]int64, 0, len(collectionList)) + for _, v := range collectionList { + productIds = append(productIds, *v.ProductId) + } + //获取产品所有模型+配件来计算最低价 + modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByProductIdsTags(l.ctx, productIds, []int{constants.TAG_MODEL, constants.TAG_PARTS}, "id,tag,product_id,part_id,price,step_price") + mapModel := make(map[int64]int) + for k, v := range modelList { + mapModel[v.Id] = k + } + //计算最低价 + mapProductMinPrice := make(map[int64]int64) + for _, v := range modelList { + if *v.Tag != constants.TAG_MODEL { + continue + } + var stepPrice gmodel.StepPriceJsonStruct + if err = json.Unmarshal(*v.StepPrice, &stepPrice); err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeJsonErr, fmt.Sprintf("failed to parse step price:%d", v.Id)) + } + //阶梯最低单价 + itemPrice := int64(0) + if len(stepPrice.PriceRange) > 0 { + itemPrice = stepPrice.PriceRange[0].Price + } + //配件价格 + if fittingIndex, ok := mapModel[*v.PartId]; ok { + itemPrice += *modelList[fittingIndex].Price + } + //查询比较最低价 + if minPrice, ok := mapProductMinPrice[*v.ProductId]; ok { + if minPrice < itemPrice { + continue + } + } + mapProductMinPrice[*v.ProductId] = itemPrice + } + //获取产品列表 + productList, err := l.svcCtx.AllModels.FsProduct.GetProductListByIdsWithoutStatus(l.ctx, productIds, "") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product list") + } + mapProduct := make(map[int64]int) + resourceIds := make([]string, 0, len(productList)) + for k, v := range productList { + mapProduct[v.Id] = k + resourceIds = append(resourceIds, s3url_to_s3id.GetS3ResourceIdFormUrl(*v.Cover)) + } + sizeCounts, err := l.svcCtx.AllModels.FsProductSize.GetGroupProductSizeByStatus(l.ctx, productIds, 1) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product size count") + } + mapProductSizeCount := make(map[int64]int64) + for _, v := range sizeCounts { + mapProductSizeCount[v.ProductId] = v.Num + } + //获取资源列表 + resourceList, err := l.svcCtx.AllModels.FsResource.FindAllByResourceIds(l.ctx, resourceIds) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get resource list") + } + mapResourceMetadata := make(map[string]interface{}) + for _, v := range resourceList { + var metadata interface{} + if err = json.Unmarshal(*v.Metadata, &metadata); err != nil { + logx.Error(err) + return resp.SetStatusAddMessage(basic.CodeJsonErr, fmt.Sprintf("failed to parse resource metadata:%s", v.ResourceId)) + } + mapResourceMetadata[*v.ResourceUrl] = metadata + } + listRsp := make([]types.GetCollectProductListRspItem, 0, len(collectionList)) + for _, collection := range collectionList { + productName := "" + cover := "" + isShelf := int64(0) + isDeleted := int64(0) + var coverMetadata interface{} + if productIndex, ok := mapProduct[*collection.ProductId]; ok { + productName = *productList[productIndex].Title + cover = *productList[productIndex].Cover + isShelf = *productList[productIndex].IsShelf + isDeleted = *productList[productIndex].IsDel + if metadata, ok := mapResourceMetadata[cover]; ok { + coverMetadata = metadata + } + } + sizeCount := int64(0) + if count, ok := mapProductSizeCount[*collection.ProductId]; ok { + sizeCount = count + } + minPrice := "" + if price, ok := mapProductMinPrice[*collection.ProductId]; ok { + minPrice = format.CentitoDollar(price, 3) + } + listRsp = append(listRsp, types.GetCollectProductListRspItem{ + Id: collection.Id, + ProductId: *collection.ProductId, + ProductName: productName, + Logo: *collection.Logo, + Cover: cover, + CoverMetadata: coverMetadata, + SelectColorIndex: *collection.SelectColorIndex, + TemplateTag: *collection.TemplateTag, + SizeCount: sizeCount, + MinPrice: minPrice, + IsShelf: isShelf, + IsDeleted: isDeleted, + }) + } + return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetCollectProductListRsp{ + Meta: types.Meta{ + TotalCount: total, + PageCount: int64(math.Ceil(float64(total) / float64(limit))), + CurrentPage: req.CurrentPage, + PerPage: limit, + }, + List: listRsp, + }) } // 处理逻辑后 w,r 如:重定向, resp 必须重新处理 diff --git a/server/collection/internal/types/types.go b/server/collection/internal/types/types.go index d67837ac..62d68266 100644 --- a/server/collection/internal/types/types.go +++ b/server/collection/internal/types/types.go @@ -20,15 +20,24 @@ type GetCollectProductListReq struct { CurrentPage int `form:"current_page"` } +type GetCollectProductListRsp struct { + Meta Meta `json:"meta"` //分页信息 + List []GetCollectProductListRspItem `json:"list"` +} + type GetCollectProductListRspItem struct { - Id int64 `json:"id"` - ProductId int64 `json:"product_id"` - ProductName string `json:"product_name"` - Logo string `json:"logo"` - SelectColorIndex int64 `json:"select_color_index"` - TemplateTag string `json:"template_tag"` - SizeCount int64 `json:"size_count"` - MinPrice string `json:"min_price"` + Id int64 `json:"id"` + ProductId int64 `json:"product_id"` + ProductName string `json:"product_name"` + Logo string `json:"logo"` + Cover string `json:"cover"` + CoverMetadata interface{} `json:"coverMetadata"` + SelectColorIndex int64 `json:"select_color_index"` + TemplateTag string `json:"template_tag"` + SizeCount int64 `json:"size_count"` + MinPrice string `json:"min_price"` + IsShelf int64 `json:"is_shelf"` + IsDeleted int64 `json:"is_deleted"` } type Request struct { diff --git a/server_api/collection.api b/server_api/collection.api index 0e24e0f2..37bcf004 100644 --- a/server_api/collection.api +++ b/server_api/collection.api @@ -35,13 +35,21 @@ type DeleteCollectProductReq { type GetCollectProductListReq { CurrentPage int `form:"current_page"` } +type GetCollectProductListRsp { + Meta Meta `json:"meta"` //分页信息 + List []GetCollectProductListRspItem `json:"list"` +} type GetCollectProductListRspItem { - Id int64 `json:"id"` - ProductId int64 `json:"product_id"` - ProductName string `json:"product_name"` - Logo string `json:"logo"` - SelectColorIndex int64 `json:"select_color_index"` - TemplateTag string `json:"template_tag"` - SizeCount int64 `json:"size_count"` - MinPrice string `json:"min_price"` + Id int64 `json:"id"` + ProductId int64 `json:"product_id"` + ProductName string `json:"product_name"` + Logo string `json:"logo"` + Cover string `json:"cover"` + CoverMetadata interface{} `json:"coverMetadata"` + SelectColorIndex int64 `json:"select_color_index"` + TemplateTag string `json:"template_tag"` + SizeCount int64 `json:"size_count"` + MinPrice string `json:"min_price"` + IsShelf int64 `json:"is_shelf"` + IsDeleted int64 `json:"is_deleted"` } \ No newline at end of file diff --git a/server_api/websocket.api b/server_api/websocket.api index 356a2fd7..620c1d8a 100644 --- a/server_api/websocket.api +++ b/server_api/websocket.api @@ -22,7 +22,7 @@ service websocket { //渲染完了通知接口 type RenderNotifyReq { - TaskId string `json:"task_id"` //任务id + " " + wid的结合字符串 + TaskId string `json:"task_id"` UserId int64 `json:"user_id"` GuestId int64 `json:"guest_id"` Image string `json:"image"`