fusenapi/server/shopping-cart-confirmation/internal/logic/cartlistlogic.go
laodaming f6cee27c3f fix
2023-06-20 18:37:56 +08:00

279 lines
8.7 KiB
Go

package logic
import (
"encoding/json"
"errors"
"fusenapi/constants"
"fusenapi/model/gmodel"
"fusenapi/utils/auth"
"fusenapi/utils/basic"
"fusenapi/utils/format"
"fusenapi/utils/image"
"fusenapi/utils/step_price"
"strings"
"sync"
"time"
"context"
"fusenapi/server/shopping-cart-confirmation/internal/svc"
"fusenapi/server/shopping-cart-confirmation/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CartListLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCartListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CartListLogic {
return &CartListLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
// 获取用户购物车列表
func (l *CartListLogic) CartList(req *types.CartListReq, userinfo *auth.UserInfo) (resp *basic.Response) {
if userinfo.GetIdType() != auth.IDTYPE_User {
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please login first")
}
//获取当前图片应该返回的尺寸大小
if req.Size > 0 {
req.Size = image.GetCurrentSize(req.Size)
}
//获取用户购物车数据
cartRelativeData, err := l.getUserCartRelativeList(l.ctx, userinfo.UserId)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get cart list data")
}
if len(cartRelativeData.CartList) == 0 {
return resp.SetStatusWithMessage(basic.CodeOK, "success")
}
//产品名map
mapProduct := make(map[int64]int)
for k, v := range cartRelativeData.ProductList {
mapProduct[v.Id] = k
}
//产品尺寸size map
mapProductSize := make(map[int64]int)
for k, v := range cartRelativeData.ProductSizeList {
mapProductSize[v.Id] = k
}
//设计map数据
mapProductDesign := make(map[int64]int)
for k, v := range cartRelativeData.ProductDesignList {
mapProductDesign[v.Id] = k
}
//产品模型map数据
mapProductModel3d := make(map[int64]int)
for k, v := range cartRelativeData.ProductModel3dList {
mapProductModel3d[v.Id] = k
}
//遍历组装数据
rspList := make([]types.CartListRsp, 0, len(cartRelativeData.CartList))
for _, v := range cartRelativeData.CartList {
name := ""
productSn := ""
if productIndex, ok := mapProduct[*v.ProductId]; ok {
name = *cartRelativeData.ProductList[productIndex].Title
productSn = strings.ToLower(*cartRelativeData.ProductList[productIndex].Sn)
}
designSn := ""
if designIndex, ok := mapProductDesign[*v.DesignId]; ok {
designSn = strings.ToLower(*cartRelativeData.ProductDesignList[designIndex].Sn)
}
pcList, err := l.getPcList(cartRelativeData.ProductPriceList, *v.ProductId, *v.MaterialId, *v.SizeId)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to calculate step price")
}
d := types.CartListRsp{
Id: v.Id,
Cover: *v.Cover,
Name: name,
Capacity: "",
ETA: time.Now().AddDate(0, 0, 60).Format("2006-01-02 15:04:05"),
Pcs: *v.BuyNum,
ProductSn: productSn,
DesignSn: designSn,
Option: nil,
IsCheck: *v.IsCheck,
TsTime: v.TsTime.Format("2006-01-02 15:04:05"),
PcsList: pcList,
Size: nil,
}
var sizeList types.CartSizeItem
if sizeIndex, ok := mapProductSize[*v.SizeId]; ok {
d.Capacity = *cartRelativeData.ProductSizeList[sizeIndex].Capacity
err = json.Unmarshal([]byte(*cartRelativeData.ProductSizeList[sizeIndex].Title), &sizeList)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to parse product size`s title")
}
d.Size = &sizeList
}
if model3dIndex, ok := mapProductModel3d[*v.OptionalId]; ok {
d.Option = &types.CartOption{
Id: cartRelativeData.ProductModel3dList[model3dIndex].Id,
Title: *cartRelativeData.ProductModel3dList[model3dIndex].Title,
Price: float64(*cartRelativeData.ProductModel3dList[model3dIndex].Price) / float64(100),
}
}
rspList = append(rspList, d)
}
return resp.SetStatusWithMessage(basic.CodeOK, "success", rspList)
}
type GetUserCartRelativeListRsp struct {
CartList []gmodel.FsCart
ProductDesignList []gmodel.FsProductDesign
ProductSizeList []gmodel.FsProductSize
ProductList []gmodel.FsProduct
ProductModel3dList []gmodel.FsProductModel3d
ProductTemplateV2List []gmodel.FsProductTemplateV2
ProductPriceList []gmodel.FsProductPrice
}
// 获取阶梯对应的价格
func (l *CartListLogic) getPcList(productPriceList []gmodel.FsProductPrice, productId int64, materialId int64, sizeId int64) (list []*types.PcsItem, err error) {
for _, price := range productPriceList {
if *price.ProductId != productId || *price.MaterialId != materialId || *price.SizeId != sizeId {
continue
}
stepNumStrSlice := strings.Split(*price.StepNum, ",")
stepNumSlice, err := format.StrSlicToIntSlice(stepNumStrSlice)
if err != nil {
return nil, err
}
stepPriceStrSlice := strings.Split(*price.StepPrice, ",")
stepPriceSlice, err := format.StrSlicToIntSlice(stepPriceStrSlice)
if err != nil {
return nil, err
}
lenStepPriceSlice := len(stepPriceSlice)
lenStepNumSlice := len(stepNumSlice)
if lenStepPriceSlice == 0 || lenStepNumSlice == 0 {
return nil, errors.New("step num or step price item count can`t be 0 ")
}
for int(*price.MinBuyNum) < stepNumSlice[lenStepNumSlice-1]+5 {
list = append(list, &types.PcsItem{
Num: *price.MinBuyNum,
TotalNum: *price.MinBuyNum * *price.EachBoxNum,
Title: *price.Title,
Price: step_price.GetStepPrice(int(*price.MinBuyNum), stepNumSlice, stepPriceSlice),
})
*price.MinBuyNum++
}
}
return list, nil
}
// 获取用户购物车数据
func (l *CartListLogic) getUserCartRelativeList(ctx context.Context, userId int64) (resp GetUserCartRelativeListRsp, err error) {
//购物车列表
cartModel := gmodel.NewFsCartModel(l.svcCtx.MysqlConn)
cartList, err := cartModel.GetAllByUserId(ctx, userId, "ctime-desc")
if err != nil {
return GetUserCartRelativeListRsp{}, err
}
if len(cartList) == 0 {
return
}
resp.CartList = cartList
productIds := make([]int64, 0, len(cartList))
sizeIds := make([]int64, 0, len(cartList))
designIds := make([]int64, 0, len(cartList))
optionIds := make([]int64, 0, len(cartList))
templateIds := make([]int64, 0, len(cartList))
for _, v := range cartList {
productIds = append(productIds, *v.ProductId)
sizeIds = append(sizeIds, *v.SizeId)
designIds = append(designIds, *v.DesignId)
optionIds = append(optionIds, *v.OptionalId)
templateIds = append(templateIds, *v.TemplateId)
}
//******************************协程并发开始***********************************
wait := sync.WaitGroup{}
errChan := make(chan error)
wait.Add(6) //注意要加协程这里要记得加
//获取产品数据1
go func() {
defer wait.Done()
productModel := gmodel.NewFsProductModel(l.svcCtx.MysqlConn)
productList, err := productModel.GetProductListByIds(ctx, productIds, "")
if err != nil {
errChan <- err
return
}
resp.ProductList = productList
}()
//获取尺寸数据2
go func() {
defer wait.Done()
productSizeModel := gmodel.NewFsProductSizeModel(l.svcCtx.MysqlConn)
productSizeList, err := productSizeModel.GetAllByIds(ctx, sizeIds, "")
if err != nil {
errChan <- err
}
resp.ProductSizeList = productSizeList
}()
//获取设计列表3
go func() {
defer wait.Done()
productDesignModel := gmodel.NewFsProductDesignModel(l.svcCtx.MysqlConn)
productDesignList, err := productDesignModel.GetAllByIds(ctx, designIds)
if err != nil {
errChan <- err
}
resp.ProductDesignList = productDesignList
}()
//获取配件列表4
go func() {
defer wait.Done()
productModel3dModel := gmodel.NewFsProductModel3dModel(l.svcCtx.MysqlConn)
productModel3dList, err := productModel3dModel.GetAllByIdsTag(ctx, optionIds, constants.TAG_PARTS)
if err != nil {
errChan <- err
}
resp.ProductModel3dList = productModel3dList
}()
//获取模板信息5
go func() {
defer wait.Done()
productTemplateModel := gmodel.NewFsProductTemplateV2Model(l.svcCtx.MysqlConn)
templateV2List, err := productTemplateModel.FindAllByIds(ctx, templateIds)
if err != nil {
errChan <- err
}
resp.ProductTemplateV2List = templateV2List
}()
//获取产品价格列表6
go func() {
defer wait.Done()
productPriceModel := gmodel.NewFsProductPriceModel(l.svcCtx.MysqlConn)
productPriceList, err := productPriceModel.GetPriceListByProductIds(ctx, productIds)
if err != nil {
errChan <- err
}
resp.ProductPriceList = productPriceList
}()
//******************************协程并发结束***********************************
go func() {
wait.Wait()
close(errChan)
}()
//获取错误信息
for err = range errChan {
if err != nil {
return GetUserCartRelativeListRsp{}, err
}
}
return resp, nil
}