package logic import ( "context" "encoding/json" "errors" "fmt" "fusenapi/constants" "fusenapi/model" "fusenapi/product/internal/svc" "fusenapi/product/internal/types" "fusenapi/utils/auth" "fusenapi/utils/format" "fusenapi/utils/image" "github.com/zeromicro/go-zero/core/stores/sqlc" "sort" "strings" "time" "github.com/zeromicro/go-zero/core/logx" ) type GetProductListLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewGetProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductListLogic { return &GetProductListLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } // 获取产品列表 func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, loginInfo auth.UserInfo) (resp *types.Response) { resp = &types.Response{} //校验前台登录情况 if loginInfo.UserId == 0 { resp.Set(constants.CODE_UNAUTH, "please sign in") return } //如果是demo if req.IsDemo == 1 { var demo types.GetProductListRsp if err := json.Unmarshal([]byte(constants.PRODUCT_LIST_DEMO), &demo); err != nil { logx.Error(err) resp.Set(constants.CODE_SERVICE_ERR, "demo data format err") } resp.SetWithData(constants.CODE_OK, "success", demo) return } if req.Page <= 0 { req.Page = 1 } //获取合适尺寸 if req.Size > 0 { req.Size = image.GetCurrentSize(req.Size) } //查询用户信息 userModel := model.NewFsUserModel(l.svcCtx.MysqlConn) userInfo, err := userModel.FindOne(l.ctx, loginInfo.UserId) if err != nil && !errors.Is(err, sqlc.ErrNotFound) { logx.Error(err) resp.Set(constants.CODE_SERVICE_ERR, "get user info err") return } if userInfo == nil { resp.Set(constants.CODE_UNAUTH, "user not exists") return } //查询符合的产品列表 productModel := model.NewFsProductModel(l.svcCtx.MysqlConn) productList, err := productModel.GetProductListByConditions(l.ctx, int(req.Cid), 0, 1, "sort-desc") if err != nil { logx.Error(err) resp.Set(constants.CODE_SERVICE_ERR, "failed to get product list") return } productLen := len(productList) if productLen == 0 { resp.Set(constants.CODE_OK, "success") return } //提取产品ids productIds := make([]string, 0, productLen) for _, v := range productList { productIds = append(productIds, fmt.Sprintf("%d", v.Id)) } productPriceModel := model.NewFsProductPriceModel(l.svcCtx.MysqlConn) productPriceList, err := productPriceModel.GetPriceList(l.ctx, productIds) if err != nil { logx.Error(err) resp.Set(constants.CODE_SERVICE_ERR, "failed to get product min price list") return } //存储产品最小价格 mapProductMinPrice := make(map[int64]int64) for _, v := range productPriceList { priceStrSlic := strings.Split(v.Price, ",") priceSlice, err := format.StrSlicToIntSlice(priceStrSlic) if err != nil { logx.Error(err) resp.Set(constants.CODE_SERVICE_ERR, err.Error()) return } if len(priceSlice) == 0 { continue } sort.Ints(priceSlice) mapProductMinPrice[v.ProductId] = int64(priceSlice[0]) } //获取模板 productTemplateModel := model.NewFsProductTemplateV2Model(l.svcCtx.MysqlConn) productTemplatesV2, err := productTemplateModel.FindAllByCondition(l.ctx, productIds) if err != nil { logx.Error(err) resp.Set(constants.CODE_SERVICE_ERR, "get product template_v2 err") return } mapProductTemplate := make(map[int64]struct{}) for _, v := range productTemplatesV2 { mapProductTemplate[v.ProductId] = struct{}{} } //获取分类 tagsModel := model.NewFsTagsModel(l.svcCtx.MysqlConn) tagInfo, err := tagsModel.FindOne(l.ctx, req.Cid) if err != nil && !errors.Is(err, sqlc.ErrNotFound) { logx.Error(err) resp.Set(constants.CODE_SERVICE_ERR, "get tag err") return } if tagInfo == nil { return &types.Response{Code: 510, Message: "classification not exists "} } //获取产品尺寸数量 productSizeModel := model.NewFsProductSizeModel(l.svcCtx.MysqlConn) productSizeCount, err := productSizeModel.CountByStatus(l.ctx, 1) if err != nil { logx.Error(err) resp.Set(constants.CODE_SERVICE_ERR, "get product size count err") return } //拼接返回 itemList := make([]types.Items, 0, productLen) for _, v := range productList { minPrice, ok := mapProductMinPrice[v.Id] //无最小价格则不显示 if !ok { continue } _, ok = mapProductTemplate[v.Id] //没有模板也不显示 if !ok { continue } item := types.Items{ Id: v.Id, Sn: v.Sn, Title: v.Title, Cover: v.Cover, Intro: v.Intro.String, CoverImg: v.CoverImg, IsEnv: v.IsProtection, IsMicro: v.IsMicrowave, SizeNum: uint32(productSizeCount), MiniPrice: format.CentoDollar(minPrice), } if req.Size > 0 { coverSlice := strings.Split(v.Cover, ".") coverImgSlice := strings.Split(v.CoverImg, ".") if req.Size >= 200 { item.Cover = fmt.Sprintf("%s_%d.%s", coverSlice[0], req.Size, coverSlice[1]) item.CoverImg = fmt.Sprintf("%s_%d.%s", coverImgSlice[0], req.Size, coverImgSlice[1]) } //千人千面处理 if userInfo.IsThousandFace == 1 { v.Cover = "" item.CoverDefault = item.CoverImg if req.Size >= 200 { item.CoverImg = fmt.Sprintf("%s/test/%d/%d_%d.png?%d", constants.DOMAIN_RENDER_IMG_NAME, userInfo.Id, userInfo.Id, v.Id, time.Now().Unix()) item.CoverDefault = fmt.Sprintf("%s_%d.%s", coverImgSlice[0], req.Size, coverImgSlice[1]) } } } itemList = append(itemList, item) } resp.SetWithData(constants.CODE_OK, "success", types.GetProductListRsp{ Ob: types.Ob{ Items: itemList, }, TypeName: tagInfo.Title, Description: tagInfo.Description, }) return }