From 9c178b2add662c1c9110ee2ca47d0853f1780e06 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Thu, 14 Sep 2023 18:33:29 +0800 Subject: [PATCH] fix --- model/gmodel/fs_shopping_cart_logic.go | 40 +++- .../internal/logic/addtocartlogic.go | 13 +- .../internal/logic/getcartslogic.go | 182 +++++++++++++++++- server/shopping-cart/internal/types/types.go | 10 +- server_api/basic.api | 8 +- server_api/shopping-cart.api | 2 +- utils/shopping_cart/shopping_cart_snapshot.go | 8 +- 7 files changed, 236 insertions(+), 27 deletions(-) diff --git a/model/gmodel/fs_shopping_cart_logic.go b/model/gmodel/fs_shopping_cart_logic.go index d9c3894c..1f508ac9 100644 --- a/model/gmodel/fs_shopping_cart_logic.go +++ b/model/gmodel/fs_shopping_cart_logic.go @@ -55,14 +55,34 @@ func (s *FsShoppingCartModel) GetAllByIds(ctx context.Context, ids []int64, sort } // 获取用户所有的购物车 -func (s *FsShoppingCartModel) GetUserAllCarts(ctx context.Context, userId int64, sort string, fields ...string) (resp []FsShoppingCart, err error) { - db := s.db.WithContext(ctx).Where("user_id = ?", userId) - if len(fields) > 0 { - db = db.Select(fields[0]) - } - if sort != "" { - db = db.Order(sort) - } - err = db.Find(&resp).Error - return resp, err +type GetAllCartsByParamReq struct { + Ids []int64 //id集合 + UserId int64 //用户id + Fields string //筛选的字段 + Sort string //排序 + Page int //当前页 + Limit int //每页数量 +} + +func (s *FsShoppingCartModel) GetAllCartsByParam(ctx context.Context, req GetAllCartsByParamReq) (resp []FsShoppingCart, total int64, err error) { + db := s.db.WithContext(ctx) + if req.UserId > 0 { + db = db.Where("user_id = ?", req.UserId) + } + if len(req.Ids) > 0 { + db = db.Where("id in (?)", req.Ids) + } + if req.Fields != "" { + db = db.Select(req.Fields) + } + if req.Sort != "" { + db = db.Order(req.Sort) + } + //查询数量 + if err = db.Limit(1).Count(&total).Error; err != nil { + return nil, 0, err + } + offset := (req.Page - 1) * req.Limit + err = db.Offset(offset).Limit(req.Limit).Find(&resp).Error + return resp, total, err } diff --git a/server/shopping-cart/internal/logic/addtocartlogic.go b/server/shopping-cart/internal/logic/addtocartlogic.go index f9ef46f3..6194aea9 100644 --- a/server/shopping-cart/internal/logic/addtocartlogic.go +++ b/server/shopping-cart/internal/logic/addtocartlogic.go @@ -53,7 +53,7 @@ func (l *AddToCartLogic) AddToCart(req *types.AddToCartReq, userinfo *auth.UserI return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "sorry,the count of your carts can`t greater than 100") } //获取产品是否存在 - _, err = l.svcCtx.AllModels.FsProduct.FindOne(l.ctx, req.ProductId, "id") + 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 exists") @@ -138,6 +138,11 @@ func (l *AddToCartLogic) AddToCart(req *types.AddToCartReq, userinfo *auth.UserI if modelInfo.ModelInfo == nil || *modelInfo.ModelInfo == "" { return resp.SetStatusWithMessage(basic.CodeServiceErr, "the model`s design info is empty") } + var sizeTitleInfo shopping_cart.SizeInfo + if err = json.Unmarshal([]byte(*sizeInfo.Title), &sizeTitleInfo); err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse size info`s title ") + } //快照数据 snapshot := shopping_cart.CartSnapshot{ Logo: req.Logo, @@ -153,8 +158,10 @@ func (l *AddToCartLogic) AddToCart(req *types.AddToCartReq, userinfo *auth.UserI FittingInfo: shopping_cart.FittingInfo{ FittingJson: fittingJson, }, - SizeInfo: shopping_cart.SizeInfo{ - Title: *sizeInfo.Title, + SizeInfo: sizeTitleInfo, + ProductInfo: shopping_cart.ProductInfo{ + ProductName: *productInfo.Title, + ProductSn: *productInfo.Sn, }, UserDiyInformation: shopping_cart.UserDiyInformation{ Phone: req.DiyInfo.Phone, diff --git a/server/shopping-cart/internal/logic/getcartslogic.go b/server/shopping-cart/internal/logic/getcartslogic.go index 097f91b7..a289d151 100644 --- a/server/shopping-cart/internal/logic/getcartslogic.go +++ b/server/shopping-cart/internal/logic/getcartslogic.go @@ -1,8 +1,15 @@ package logic import ( + "encoding/json" + "fusenapi/constants" + "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" + "fusenapi/utils/hash" + "fusenapi/utils/shopping_cart" + "math" + "strings" "context" @@ -31,12 +38,181 @@ func NewGetCartsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetCarts // } func (l *GetCartsLogic) GetCarts(req *types.GetCartsReq, userinfo *auth.UserInfo) (resp *basic.Response) { - // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) - // userinfo 传入值时, 一定不为null - + if req.CurrentPage <= 0 { + req.CurrentPage = constants.DEFAULT_PAGE + } + limit := 10 + //获取用户购物车列表 + carts, total, err := l.svcCtx.AllModels.FsShoppingCart.GetAllCartsByParam(l.ctx, gmodel.GetAllCartsByParamReq{ + UserId: userinfo.UserId, + Fields: "", + Sort: "id DESC", + Page: req.CurrentPage, + Limit: limit, + }) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "system err:failed to get your shopping carts") + } + if len(carts) == 0 { + return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetCartsRsp{ + Meta: types.Meta{ + TotalCount: total, + PageCount: int64(math.Ceil(float64(total) / float64(limit))), + CurrentPage: req.CurrentPage, + PerPage: limit, + }, + CartList: nil, + }) + } + lenCarts := len(carts) + templateIds := make([]int64, 0, lenCarts) + modelIds := make([]int64, 0, lenCarts) //模型 + 配件 + sizeIds := make([]int64, 0, lenCarts) + for index := range carts { + templateIds = append(templateIds, *carts[index].TemplateId) + modelIds = append(modelIds, *carts[index].ModelId, *carts[index].FittingId) + sizeIds = append(sizeIds, *carts[index].SizeId) + } + //获取尺寸列表 + sizeList, err := l.svcCtx.AllModels.FsProductSize.GetAllByIds(l.ctx, sizeIds, "") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get size list") + } + mapSize := make(map[int64]gmodel.FsProductSize) + for _, v := range sizeList { + mapSize[v.Id] = v + } + //获取模型和配件信息 + modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByIds(l.ctx, modelIds, "") + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get model list") + } + mapModel := make(map[int64]gmodel.FsProductModel3d) + for _, v := range modelList { + mapModel[v.Id] = v + } + //获取模板列表 + templateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByIds(l.ctx, templateIds) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get template list") + } + mapTemplate := make(map[int64]gmodel.FsProductTemplateV2) + for _, v := range templateList { + mapTemplate[v.Id] = v + } + //定义map收集变更信息 + mapCartChange := make(map[int64]string) + //校验购物车数据是否变更 + err = VerifyShoppingCartSnapshotDataChange(VerifyShoppingCartSnapshotDataChangeReq{ + Carts: carts, + MapSize: mapSize, + MapModel: mapModel, + MapTemplate: mapTemplate, + MapCartChange: mapCartChange, + }) + if err != nil { + logx.Error("VerifyShoppingCartSnapshotDataChange err:", err.Error()) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "system err:failed to check shopping cart change data") + } + //for index return resp.SetStatus(basic.CodeOK) } +// 校验购物车快照数据跟目前是否一致 +type VerifyShoppingCartSnapshotDataChangeReq struct { + Carts []gmodel.FsShoppingCart + MapSize map[int64]gmodel.FsProductSize + MapModel map[int64]gmodel.FsProductModel3d //模型跟配件都在 + MapTemplate map[int64]gmodel.FsProductTemplateV2 + MapCartChange map[int64]string +} +type VerifyShoppingCartSnapshotDataChangeRsp struct { + CartId int64 //有改变的列表下标 + Descrption string //变更描述信息 +} + +func VerifyShoppingCartSnapshotDataChange(req VerifyShoppingCartSnapshotDataChangeReq) error { + for _, cartInfo := range req.Carts { + var snapShotParseInfo shopping_cart.CartSnapshot + if err := json.Unmarshal([]byte(*cartInfo.Snapshot), &snapShotParseInfo); err != nil { + return err + } + //快照中模板设计json数据哈希值 + snapshotTemplateJsonHash := hash.JsonHashKey(snapShotParseInfo.TemplateInfo.TemplateJson) + //快照中模型设计json数据哈希值 + snapshotModelJsonHash := hash.JsonHashKey(snapShotParseInfo.ModelInfo.ModelJson) + //快照中配件设计json数据哈希值 + snapshotFittingJsonHash := hash.JsonHashKey(snapShotParseInfo.FittingInfo.FittingJson) + descrptionBuilder := strings.Builder{} + //有模板验证模板相关 + if *cartInfo.TemplateId > 0 { + if curTemplateInfo, ok := req.MapTemplate[*cartInfo.TemplateId]; !ok { + descrptionBuilder.WriteString("
the template is lose
") + } else { + //当前模板设计json数据哈希值 + curTemplateJsonHash := hash.JsonHashKey(*curTemplateInfo.TemplateInfo) + //模板设计信息改变了 + if snapshotTemplateJsonHash != curTemplateJsonHash { + descrptionBuilder.WriteString("the template design info has changed
") + } + //模板标签改变了 + if snapShotParseInfo.TemplateInfo.TemplateTag != *curTemplateInfo.TemplateTag { + descrptionBuilder.WriteString("the template`s template tag has changed
") + } + } + } + //有模型验证模型相关 + if *cartInfo.ModelId > 0 { + if curModelInfo, ok := req.MapModel[*cartInfo.ModelId]; !ok { //不存在 + descrptionBuilder.WriteString("the model is lose
") + } else { + //当前模型设计json数据哈希值 + curModelJsonHash := hash.JsonHashKey(*curModelInfo.ModelInfo) + if snapshotModelJsonHash != curModelJsonHash { + descrptionBuilder.WriteString("the model design info has changed
") + } + } + } + //有配件验证配件相关 + if *cartInfo.FittingId > 0 { + if curFittingInfo, ok := req.MapModel[*cartInfo.FittingId]; !ok { //不存在 + descrptionBuilder.WriteString("the fitting is lose
") + } else { + //当前配件设计json数据哈希值 + curFittingJsonHash := hash.JsonHashKey(*curFittingInfo.ModelInfo) + if snapshotFittingJsonHash != curFittingJsonHash { + descrptionBuilder.WriteString("the fitting design info has changed
") + } + } + } + //验证尺寸相关 + if *cartInfo.SizeId > 0 { + curSize, ok := req.MapSize[*cartInfo.SizeId] + if !ok { + descrptionBuilder.WriteString("the size is lose
") + } else { + var curSizeTitle shopping_cart.SizeInfo + if err := json.Unmarshal([]byte(*curSize.Title), &curSizeTitle); err != nil { + return err + } + if snapShotParseInfo.SizeInfo.Inch != curSizeTitle.Inch || snapShotParseInfo.SizeInfo.Cm != curSizeTitle.Cm { + descrptionBuilder.WriteString("the size design info has changed
") + } + } + } + //收集错误 + descrption := descrptionBuilder.String() + if descrption != "" { + req.MapCartChange[cartInfo.Id] = descrption + } + } + return nil +} + // 处理逻辑后 w,r 如:重定向, resp 必须重新处理 // func (l *GetCartsLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { // // httpx.OkJsonCtx(r.Context(), w, resp) diff --git a/server/shopping-cart/internal/types/types.go b/server/shopping-cart/internal/types/types.go index aa61eb09..fc3f605c 100644 --- a/server/shopping-cart/internal/types/types.go +++ b/server/shopping-cart/internal/types/types.go @@ -35,7 +35,7 @@ type ModifyCartPurchaseQuantityReq struct { } type GetCartsReq struct { - Page int `form:"page"` //当前页 + CurrentPage int `form:"current_page"` //当前页 } type GetCartsRsp struct { @@ -99,10 +99,10 @@ type File struct { } type Meta struct { - TotalCount int64 `json:"totalCount"` - PageCount int64 `json:"pageCount"` - CurrentPage int `json:"currentPage"` - PerPage int `json:"perPage"` + TotalCount int64 `json:"total_count"` + PageCount int64 `json:"page_count"` + CurrentPage int `json:"current_page"` + PerPage int `json:"per_page"` } // Set 设置Response的Code和Message值 diff --git a/server_api/basic.api b/server_api/basic.api index 7125abc4..be14515d 100644 --- a/server_api/basic.api +++ b/server_api/basic.api @@ -36,8 +36,8 @@ type File { // 统一分页 type Meta struct { - TotalCount int64 `json:"totalCount"` - PageCount int64 `json:"pageCount"` - CurrentPage int `json:"currentPage"` - PerPage int `json:"perPage"` + TotalCount int64 `json:"total_count"` + PageCount int64 `json:"page_count"` + CurrentPage int `json:"current_page"` + PerPage int `json:"per_page"` } \ No newline at end of file diff --git a/server_api/shopping-cart.api b/server_api/shopping-cart.api index 3824f27f..3f1f19c5 100644 --- a/server_api/shopping-cart.api +++ b/server_api/shopping-cart.api @@ -53,7 +53,7 @@ type ModifyCartPurchaseQuantityReq { } //获取购物车列表 type GetCartsReq { - Page int `form:"page"` //当前页 + CurrentPage int `form:"current_page"` //当前页 } type GetCartsRsp { Meta Meta `json:"meta"` //分页信息 diff --git a/utils/shopping_cart/shopping_cart_snapshot.go b/utils/shopping_cart/shopping_cart_snapshot.go index 30705c06..b0ab5797 100644 --- a/utils/shopping_cart/shopping_cart_snapshot.go +++ b/utils/shopping_cart/shopping_cart_snapshot.go @@ -9,8 +9,13 @@ type CartSnapshot struct { ModelInfo ModelInfo `json:"model_info"` //模型的数据 FittingInfo FittingInfo `json:"fitting_info"` //配件信息 SizeInfo SizeInfo `json:"size_info"` //尺寸基本信息 + ProductInfo ProductInfo `json:"product_info"` //产品基本信息(只记录不要使用) UserDiyInformation UserDiyInformation `json:"user_diy_information"` //用户diy数据 } +type ProductInfo struct { + ProductName string `json:"product_name"` + ProductSn string `json:"product_sn"` +} type ModelInfo struct { ModelJson string `json:"model_json"` //模型设计json数据 } @@ -22,7 +27,8 @@ type TemplateInfo struct { TemplateTag string `json:"template_tag"` //模板标签 } type SizeInfo struct { - Title string `json:"title"` //尺寸信息 + Inch string `json:"inch"` + Cm string `json:"cm"` } type UserDiyInformation struct { Phone string `json:"phone"` //电话