This commit is contained in:
laodaming 2023-09-25 17:20:44 +08:00
parent 29c7dc54e3
commit 4bbe9aaaa3
5 changed files with 89 additions and 179 deletions

View File

@ -4,6 +4,18 @@ import (
"context"
)
// 阶梯价结构
type StepPriceJsonStruct struct {
PriceRange []struct {
Label string `json:"label"`
Price int64 `json:"price"`
EndQuantity int64 `json:"end_quantity"`
StartQuantity int64 `json:"start_quantity"`
} `json:"price_range"`
MinBuyUnitsNum int64 `json:"min_buy_units_num"`
StepBuyUnitsNum int64 `json:"step_buy_units_num"`
}
func (d *FsProductModel3dModel) FindOne(ctx context.Context, id int64, fields ...string) (resp *FsProductModel3d, err error) {
db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).Where("`id` = ? ", id)
if len(fields) > 0 {
@ -120,3 +132,14 @@ func (d *FsProductModel3dModel) GetOneBySizeIdTag(ctx context.Context, sizeId in
err = db.Take(&resp).Error
return resp, err
}
func (d *FsProductModel3dModel) GetAllByProductIdTag(ctx context.Context, productId int64, tag int64, fields ...string) (resp []FsProductModel3d, err error) {
db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).
Where("`product_id` = ? and `tag` = ? and `status` = ?", productId, tag, 1).
Order("sort DESC")
if len(fields) != 0 {
db = db.Select(fields[0])
}
err = db.Find(&resp).Error
return resp, err
}

View File

@ -34,7 +34,6 @@ func NewGetPriceByPidLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Get
svcCtx: svcCtx,
}
}
func (l *GetPriceByPidLogic) GetPriceByPid(req *types.GetPriceByPidReq, userinfo *auth.UserInfo) (resp *basic.Response) {
req.Pid = strings.Trim(req.Pid, " ")
if req.Pid == "" {

View File

@ -1,16 +1,10 @@
package logic
import (
"context"
"errors"
"fmt"
"fusenapi/constants"
"fusenapi/model/gmodel"
"fusenapi/utils/auth"
"fusenapi/utils/basic"
"fusenapi/utils/format"
"fusenapi/utils/step_price"
"strings"
"context"
"fusenapi/server/product/internal/svc"
"fusenapi/server/product/internal/types"
@ -32,157 +26,18 @@ func NewGetSizeByProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
}
}
// 获取分类下的产品以及尺寸
// 处理进入前逻辑w,r
// func (l *GetSizeByProductLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
// }
func (l *GetSizeByProductLogic) GetSizeByProduct(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
if userinfo.GetIdType() != auth.IDTYPE_User {
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in first")
}
//获取所有网站目录
tagsModel := gmodel.NewFsTagsModel(l.svcCtx.MysqlConn)
tagsList, err := tagsModel.GetAllByLevel(l.ctx, constants.TYPE_WEBSITE)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get website tags")
}
if len(tagsList) == 0 {
return resp.SetStatusWithMessage(basic.CodeOK, "tag list is null")
}
tagIds := make([]int64, 0, len(tagsList))
for _, v := range tagsList {
tagIds = append(tagIds, v.Id)
}
//获取这些类型的产品
productModel := gmodel.NewFsProductModel(l.svcCtx.MysqlConn)
productList, err := productModel.GetProductListByIds(l.ctx, tagIds, "sort-desc")
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get tag product list")
}
productIds := make([]int64, 0, len(productList))
for _, v := range productList {
productIds = append(productIds, v.Id)
}
productSizeModel := gmodel.NewFsProductSizeModel(l.svcCtx.MysqlConn)
productSizeList, err := productSizeModel.GetAllByProductIds(l.ctx, productIds, "sort DESC")
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product size list")
}
sizeIds := make([]int64, 0, len(productSizeList))
for _, v := range productSizeList {
sizeIds = append(sizeIds, v.Id)
}
//获取价格列表
productPriceModel := gmodel.NewFsProductPriceModel(l.svcCtx.MysqlConn)
productPriceList, err := productPriceModel.GetPriceListByProductIdsSizeIds(l.ctx, productIds, sizeIds)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product proce list")
}
mapProductPrice := make(map[string]gmodel.FsProductPrice)
for _, v := range productPriceList {
mapProductPrice[fmt.Sprintf("%d_%d", *v.ProductId, *v.SizeId)] = v
}
//组装返回
list := make([]types.GetSizeByProductRsp, 0, len(tagsList))
for _, tag := range tagsList {
//获取第一层子类
firstChildrenList, err := l.GetFirstChildrenList(tag, productList, productSizeList, mapProductPrice)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get first level children list")
}
data := types.GetSizeByProductRsp{
Id: tag.Id,
Name: *tag.Title,
Children: firstChildrenList,
}
list = append(list, data)
}
return resp.SetStatusWithMessage(basic.CodeOK, "success", list)
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
// userinfo 传入值时, 一定不为null
return resp.SetStatus(basic.CodeOK)
}
// 第一层子层
func (l *GetSizeByProductLogic) GetFirstChildrenList(tag gmodel.FsTags, productList []gmodel.FsProduct, productSizeList []gmodel.FsProductSize, mapProductPrice map[string]gmodel.FsProductPrice) (childrenList []types.Children, err error) {
childrenList = make([]types.Children, 0, len(productList))
for _, product := range productList {
if *product.Type != tag.Id {
continue
}
childrenObjList, err := l.GetSecondChildrenList(product, productSizeList, mapProductPrice)
if err != nil {
return nil, err
}
//获取第二层子类
data := types.Children{
Id: product.Id,
Name: *product.Title,
Cycle: int(*product.DeliveryDays + *product.ProduceDays),
ChildrenList: childrenObjList,
}
childrenList = append(childrenList, data)
}
return
}
// 第2层子层
func (l *GetSizeByProductLogic) GetSecondChildrenList(product gmodel.FsProduct, productSizeList []gmodel.FsProductSize, mapProductPrice map[string]gmodel.FsProductPrice) (childrenObjList []types.ChildrenObj, err error) {
childrenObjList = make([]types.ChildrenObj, 0, len(productSizeList))
for _, productSize := range productSizeList {
if product.Id != *productSize.ProductId {
continue
}
priceList := make([]types.PriceObj, 0, len(productSizeList))
price, ok := mapProductPrice[fmt.Sprintf("%d_%d", *productSize.ProductId, productSize.Id)]
//无对应尺寸价格
if !ok {
priceList = []types.PriceObj{
{Num: 1, Price: 0},
{Num: 1, Price: 0},
{Num: 1, Price: 0},
}
childrenObjList = append(childrenObjList, types.ChildrenObj{
Id: productSize.Id,
Name: *productSize.Capacity,
PriceList: priceList,
})
continue
}
if price.StepNum == nil || price.StepPrice == nil {
continue
}
*price.StepNum = strings.Trim(*price.StepNum, " ")
*price.StepPrice = strings.Trim(*price.StepPrice, " ")
//阶梯数量切片
stepNum, err := format.StrSlicToIntSlice(strings.Split(*price.StepNum, ","))
if err != nil {
return nil, err
}
//阶梯价格切片
stepPrice, err := format.StrSlicToIntSlice(strings.Split(*price.StepPrice, ","))
if err != nil {
return nil, err
}
if len(stepNum) == 0 || len(stepPrice) == 0 {
return nil, errors.New(fmt.Sprintf("stepNum count or stepPrice count is empty: product size id :%d ,product price id :%d", productSize.Id, price.Id))
}
index := 0
// 最小购买数量小于 最大阶梯数量+5
for int(*price.MinBuyNum) < (stepNum[len(stepNum)-1]+5) && index < 3 {
priceList = append(priceList, types.PriceObj{
Num: int(*price.MinBuyNum * *price.EachBoxNum),
Price: step_price.GetStepPrice(int(*price.MinBuyNum), stepNum, stepPrice),
})
*price.MinBuyNum++
index++
}
data := types.ChildrenObj{
Id: productSize.Id,
Name: *productSize.Capacity,
PriceList: priceList,
}
childrenObjList = append(childrenObjList, data)
}
return
}
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
// func (l *GetSizeByProductLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
// // httpx.OkJsonCtx(r.Context(), w, resp)
// }

View File

@ -440,10 +440,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值

View File

@ -1,20 +1,9 @@
package step_price
// 返回美元
func GetStepPrice(minBuyNum int, stepNum []int, stepPrice []int) float64 {
if minBuyNum > stepNum[len(stepNum)-1] {
return float64(stepPrice[len(stepPrice)-1]) / float64(1000)
}
for k, v := range stepNum {
if minBuyNum <= v {
if k <= (len(stepPrice) - 1) {
return float64(stepPrice[k]) / float64(1000)
}
return float64(stepPrice[len(stepPrice)-1]) / float64(1000)
}
}
return float64(stepPrice[len(stepPrice)-1]) / float64(1000)
}
import (
"errors"
"fusenapi/model/gmodel"
)
// 返回厘
func GetCentStepPrice(minBuyNum int, stepNum []int, stepPrice []int) int64 {
@ -31,3 +20,47 @@ func GetCentStepPrice(minBuyNum int, stepNum []int, stepPrice []int) int64 {
}
return int64(stepPrice[len(stepPrice)-1])
}
// 新的阶梯价格(返回美元)
func GetNewStepPrice(purchaseQuantity int64, stepPrice gmodel.StepPriceJsonStruct, fittingPrice int64) (price float64, err error) {
l := len(stepPrice.PriceRange)
if l == 0 {
return 0, errors.New("price range is not set")
}
//遍历查询合适的价格
for k, v := range stepPrice.PriceRange {
//购买数量>起点
if purchaseQuantity > v.StartQuantity {
//最后一个 || 小于等于终点
if k == l-1 || purchaseQuantity <= v.EndQuantity {
return float64(v.Price+fittingPrice) / 1000, nil
}
}
}
//遍历里面没有则返回第一个
return float64(stepPrice.PriceRange[0].Price+fittingPrice) / 1000, nil
}
// 新的阶梯价格(返回厘)
func GetNewCentStepPrice(purchaseQuantity int64, stepPrice gmodel.StepPriceJsonStruct, fittingPrice int64) (price int64, err error) {
l := len(stepPrice.PriceRange)
if l == 0 {
return 0, errors.New("price range is not set")
}
//遍历查询合适的价格
for k, v := range stepPrice.PriceRange {
//购买数量>起点
if purchaseQuantity > v.StartQuantity {
//最后一个
if k == l-1 {
return v.Price + fittingPrice, nil
}
//小于等于终点
if purchaseQuantity <= v.EndQuantity {
return v.Price + fittingPrice, nil
}
}
}
//遍历里面没有则返回第一个
return stepPrice.PriceRange[0].Price + fittingPrice, nil
}