2023-06-01 07:32:28 +00:00
|
|
|
package logic
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2023-06-02 11:24:58 +00:00
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fusenapi/constants"
|
2023-06-12 08:47:48 +00:00
|
|
|
"fusenapi/model/gmodel"
|
2023-06-08 03:03:20 +00:00
|
|
|
"fusenapi/server/product/internal/svc"
|
|
|
|
"fusenapi/server/product/internal/types"
|
2023-06-02 04:12:51 +00:00
|
|
|
"fusenapi/utils/auth"
|
2023-06-07 04:21:07 +00:00
|
|
|
"fusenapi/utils/basic"
|
2023-06-02 11:24:58 +00:00
|
|
|
"fusenapi/utils/format"
|
2023-06-01 10:52:15 +00:00
|
|
|
"fusenapi/utils/image"
|
2023-06-06 11:21:07 +00:00
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
2023-06-05 04:21:15 +00:00
|
|
|
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
2023-06-20 09:28:28 +00:00
|
|
|
"gorm.io/gorm"
|
2023-07-13 03:36:02 +00:00
|
|
|
"math"
|
2023-06-02 11:24:58 +00:00
|
|
|
"sort"
|
|
|
|
"strings"
|
2023-06-01 07:32:28 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取产品列表
|
2023-06-15 04:00:32 +00:00
|
|
|
func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
2023-06-02 11:24:58 +00:00
|
|
|
//如果是demo
|
|
|
|
if req.IsDemo == 1 {
|
|
|
|
var demo types.GetProductListRsp
|
2023-06-06 07:08:17 +00:00
|
|
|
if err := json.Unmarshal([]byte(constants.PRODUCT_LIST_DEMO), &demo); err != nil {
|
2023-06-02 11:24:58 +00:00
|
|
|
logx.Error(err)
|
2023-06-07 09:27:17 +00:00
|
|
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, "demo data format err")
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
2023-06-07 04:21:07 +00:00
|
|
|
return resp.SetStatusWithMessage(basic.CodeOK, "success", demo)
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
2023-07-13 03:36:02 +00:00
|
|
|
if req.Page <= 0 && req.Page > 10000 {
|
|
|
|
req.Page = constants.DEFAULT_PAGE
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
2023-06-01 07:32:28 +00:00
|
|
|
//获取合适尺寸
|
|
|
|
if req.Size > 0 {
|
|
|
|
req.Size = image.GetCurrentSize(req.Size)
|
|
|
|
}
|
2023-07-13 03:36:02 +00:00
|
|
|
pageSize := constants.DEFAULT_PAGE_SIZE
|
2023-07-11 09:08:19 +00:00
|
|
|
//查询用户信息(不用判断存在)
|
2023-06-12 08:47:48 +00:00
|
|
|
userModel := gmodel.NewFsUserModel(l.svcCtx.MysqlConn)
|
2023-07-11 09:08:19 +00:00
|
|
|
user, err := userModel.FindUserById(l.ctx, userinfo.UserId)
|
|
|
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
2023-06-02 11:24:58 +00:00
|
|
|
logx.Error(err)
|
2023-06-07 09:27:17 +00:00
|
|
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, "get user info err")
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
|
|
|
//查询符合的产品列表
|
2023-06-12 08:47:48 +00:00
|
|
|
productModel := gmodel.NewFsProductModel(l.svcCtx.MysqlConn)
|
2023-07-13 03:36:02 +00:00
|
|
|
productList, total, err := productModel.GetProductListByTypeIds(l.ctx, []int64{req.Cid}, int(req.Page), pageSize, "sort-desc")
|
2023-06-01 10:34:41 +00:00
|
|
|
if err != nil {
|
2023-06-02 11:24:58 +00:00
|
|
|
logx.Error(err)
|
2023-06-07 09:27:17 +00:00
|
|
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product list")
|
2023-06-01 10:34:41 +00:00
|
|
|
}
|
2023-06-02 11:24:58 +00:00
|
|
|
productLen := len(productList)
|
|
|
|
if productLen == 0 {
|
2023-06-07 09:27:17 +00:00
|
|
|
return resp.SetStatusWithMessage(basic.CodeOK, "success")
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
|
|
|
//提取产品ids
|
2023-06-12 08:47:48 +00:00
|
|
|
productIds := make([]int64, 0, productLen)
|
2023-06-02 11:24:58 +00:00
|
|
|
for _, v := range productList {
|
2023-06-12 08:47:48 +00:00
|
|
|
productIds = append(productIds, v.Id)
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
2023-06-12 08:47:48 +00:00
|
|
|
productPriceModel := gmodel.NewFsProductPriceModel(l.svcCtx.MysqlConn)
|
2023-06-13 09:47:48 +00:00
|
|
|
productPriceList, err := productPriceModel.GetSimplePriceListByProductIds(l.ctx, productIds)
|
2023-06-02 11:24:58 +00:00
|
|
|
if err != nil {
|
|
|
|
logx.Error(err)
|
2023-06-07 09:27:17 +00:00
|
|
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product min price list")
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
|
|
|
//存储产品最小价格
|
|
|
|
mapProductMinPrice := make(map[int64]int64)
|
|
|
|
for _, v := range productPriceList {
|
2023-06-05 02:18:31 +00:00
|
|
|
priceStrSlic := strings.Split(v.Price, ",")
|
|
|
|
priceSlice, err := format.StrSlicToIntSlice(priceStrSlic)
|
2023-06-02 11:24:58 +00:00
|
|
|
if err != nil {
|
|
|
|
logx.Error(err)
|
2023-06-07 09:27:17 +00:00
|
|
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error())
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
2023-06-05 02:18:31 +00:00
|
|
|
if len(priceSlice) == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
sort.Ints(priceSlice)
|
|
|
|
mapProductMinPrice[v.ProductId] = int64(priceSlice[0])
|
2023-06-01 10:34:41 +00:00
|
|
|
}
|
2023-06-02 11:24:58 +00:00
|
|
|
//获取模板
|
2023-06-12 08:47:48 +00:00
|
|
|
productTemplateModel := gmodel.NewFsProductTemplateV2Model(l.svcCtx.MysqlConn)
|
|
|
|
productTemplatesV2, err := productTemplateModel.FindAllByProductIds(l.ctx, productIds)
|
2023-06-02 11:24:58 +00:00
|
|
|
if err != nil {
|
|
|
|
logx.Error(err)
|
2023-06-07 09:27:17 +00:00
|
|
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, "get product template_v2 err")
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
|
|
|
mapProductTemplate := make(map[int64]struct{})
|
|
|
|
for _, v := range productTemplatesV2 {
|
2023-06-12 08:47:48 +00:00
|
|
|
mapProductTemplate[*v.ProductId] = struct{}{}
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
|
|
|
//获取分类
|
2023-06-12 08:47:48 +00:00
|
|
|
tagsModel := gmodel.NewFsTagsModel(l.svcCtx.MysqlConn)
|
2023-06-02 11:24:58 +00:00
|
|
|
tagInfo, err := tagsModel.FindOne(l.ctx, req.Cid)
|
2023-06-05 04:21:15 +00:00
|
|
|
if err != nil && !errors.Is(err, sqlc.ErrNotFound) {
|
2023-06-20 09:28:28 +00:00
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, "tag is not exists")
|
|
|
|
}
|
2023-06-02 11:24:58 +00:00
|
|
|
logx.Error(err)
|
2023-06-07 09:27:17 +00:00
|
|
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, "get tag err")
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
2023-06-05 09:13:05 +00:00
|
|
|
//获取产品尺寸数量
|
2023-06-12 08:47:48 +00:00
|
|
|
productSizeModel := gmodel.NewFsProductSizeModel(l.svcCtx.MysqlConn)
|
2023-07-11 09:08:19 +00:00
|
|
|
productSizeCountList, err := productSizeModel.GetGroupProductSizeByStatus(l.ctx, productIds, 1)
|
2023-06-05 09:13:05 +00:00
|
|
|
if err != nil {
|
|
|
|
logx.Error(err)
|
2023-06-07 09:27:17 +00:00
|
|
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, "get product size count err")
|
2023-06-05 09:13:05 +00:00
|
|
|
}
|
2023-07-10 10:28:37 +00:00
|
|
|
mapProductSizeCount := make(map[int64]int64)
|
2023-07-11 09:08:19 +00:00
|
|
|
for _, v := range productSizeCountList {
|
2023-07-10 10:28:37 +00:00
|
|
|
mapProductSizeCount[v.ProductId] = v.Num
|
|
|
|
}
|
2023-06-02 11:24:58 +00:00
|
|
|
//拼接返回
|
2023-06-29 03:43:07 +00:00
|
|
|
itemList := make([]types.Items, 0, productLen)
|
2023-06-02 11:24:58 +00:00
|
|
|
for _, v := range productList {
|
|
|
|
minPrice, ok := mapProductMinPrice[v.Id]
|
2023-06-06 11:43:22 +00:00
|
|
|
_, tmpOk := mapProductTemplate[v.Id]
|
|
|
|
//无最小价格则不显示 || 没有模板也不显示
|
|
|
|
if !ok || !tmpOk {
|
2023-06-02 11:24:58 +00:00
|
|
|
continue
|
|
|
|
}
|
2023-07-10 10:28:37 +00:00
|
|
|
sizeNum := int64(0)
|
2023-07-11 09:08:19 +00:00
|
|
|
if mapSizeNum, ok := mapProductSizeCount[v.Id]; ok {
|
2023-07-10 10:28:37 +00:00
|
|
|
sizeNum = mapSizeNum
|
|
|
|
}
|
2023-06-29 03:43:07 +00:00
|
|
|
item := types.Items{
|
2023-06-02 11:24:58 +00:00
|
|
|
Id: v.Id,
|
2023-06-12 08:47:48 +00:00
|
|
|
Sn: *v.Sn,
|
|
|
|
Title: *v.Title,
|
|
|
|
Intro: *v.Intro,
|
|
|
|
IsEnv: *v.IsProtection,
|
|
|
|
IsMicro: *v.IsMicrowave,
|
2023-07-10 10:28:37 +00:00
|
|
|
SizeNum: uint32(sizeNum),
|
2023-07-10 10:32:54 +00:00
|
|
|
MiniPrice: minPrice,
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
2023-06-06 11:21:07 +00:00
|
|
|
//千人千面处理
|
2023-07-11 09:08:19 +00:00
|
|
|
r := image.ThousandFaceImageFormatReq{
|
2023-06-06 11:21:07 +00:00
|
|
|
Size: int(req.Size),
|
2023-07-11 09:08:19 +00:00
|
|
|
IsThousandFace: 0,
|
2023-06-12 08:47:48 +00:00
|
|
|
Cover: *v.Cover,
|
|
|
|
CoverImg: *v.CoverImg,
|
|
|
|
CoverDefault: *v.CoverImg,
|
2023-06-06 11:21:07 +00:00
|
|
|
ProductId: v.Id,
|
2023-07-11 09:08:19 +00:00
|
|
|
UserId: user.Id,
|
|
|
|
}
|
|
|
|
if user.Id != 0 {
|
|
|
|
r.IsThousandFace = int(*user.IsThousandFace)
|
2023-06-02 11:24:58 +00:00
|
|
|
}
|
2023-07-11 09:08:19 +00:00
|
|
|
image.ThousandFaceImageFormat(&r)
|
|
|
|
item.Cover = r.Cover
|
|
|
|
item.CoverImg = r.CoverImg
|
|
|
|
item.CoverDefault = r.CoverDefault
|
2023-06-02 11:24:58 +00:00
|
|
|
itemList = append(itemList, item)
|
|
|
|
}
|
2023-06-07 04:21:07 +00:00
|
|
|
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetProductListRsp{
|
2023-06-06 07:08:17 +00:00
|
|
|
Ob: types.Ob{
|
|
|
|
Items: itemList,
|
2023-07-13 03:36:02 +00:00
|
|
|
Meta: types.Meta{
|
|
|
|
TotalCount: total,
|
|
|
|
PageCount: int64(math.Ceil(float64(total) / float64(pageSize))),
|
|
|
|
CurrentPage: int(req.Page),
|
|
|
|
PerPage: pageSize,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
TypeName: *tagInfo.Title,
|
|
|
|
Description: *tagInfo.Description,
|
2023-06-06 08:14:02 +00:00
|
|
|
})
|
2023-06-01 07:32:28 +00:00
|
|
|
}
|