|
|
package goods
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
"recook/internal/back"
|
|
|
"recook/internal/dbc"
|
|
|
"recook/internal/model/goods"
|
|
|
"recook/internal/v2/lib/es"
|
|
|
ac2 "recook/internal/v2/model/jyy"
|
|
|
"recook/internal/v2/model/keywords"
|
|
|
goods2 "recook/internal/v2/model/recook/goods"
|
|
|
"recook/internal/v2/model/recook/user"
|
|
|
"recook/internal/v2/model/search_ali"
|
|
|
"recook/tools"
|
|
|
"strings"
|
|
|
|
|
|
mysql2 "git.oa00.com/go/mysql"
|
|
|
"github.com/gin-gonic/gin"
|
|
|
"github.com/golangkit/formatime"
|
|
|
"github.com/shopspring/decimal"
|
|
|
gorm2 "gorm.io/gorm"
|
|
|
"gorm.io/gorm/clause"
|
|
|
)
|
|
|
|
|
|
type queryOrderGoodsListParam struct {
|
|
|
SecondCategoryID uint `json:"secondCategoryID"`
|
|
|
BrandID uint `json:"brandID"`
|
|
|
Page uint `json:"page"`
|
|
|
Order string `json:"order"` /*asc 升序 desc 降序*/
|
|
|
Keyword string `json:"keyword" form:"keyword"` /* 搜索的关键字 */
|
|
|
CountryId uint `json:"country_id"`
|
|
|
UserId uint `json:"user_id"`
|
|
|
Kind uint `json:"kind"`
|
|
|
ActivityID uint `json:"activity_id"` // 批发活动商品
|
|
|
IsSale bool `json:"is_sale"`
|
|
|
}
|
|
|
|
|
|
type QueryCategoryGoodsListResp struct {
|
|
|
ID uint `json:"id"`
|
|
|
GoodsName string `json:"goodsName"`
|
|
|
BrandImg string `json:"brandImg"`
|
|
|
BrandName string `json:"brandName"`
|
|
|
BrandId uint `json:"brandId"`
|
|
|
Description string `json:"description"`
|
|
|
Inventory uint `json:"inventory"` // 总库存
|
|
|
SalesVolume uint `json:"salesVolume"` // 总销量
|
|
|
MainPhotoURL string `json:"mainPhotoUrl"` // 主图链接
|
|
|
PromotionName string `json:"promotionName"`
|
|
|
OriginalPrice decimal.Decimal `json:"originalPrice"`
|
|
|
DiscountPrice decimal.Decimal `json:"discountPrice"`
|
|
|
Commission decimal.Decimal `json:"commission"`
|
|
|
Tags []string `json:"tags"` // 为产品打上标签,比如 "新人特惠" "限时特卖"
|
|
|
Percent uint `json:"percent"` // 活动的%-1代表不是活动
|
|
|
StartTime formatime.Second `json:"startTime"` // 开始时间
|
|
|
EndTime formatime.Second `json:"endTime"` // 结束时间
|
|
|
Coupon decimal.Decimal `gorm:"coupon" json:"coupon"`
|
|
|
IsImport int `json:"isImport"` //是否进口商品
|
|
|
Storehouse int `json:"storehouse"` //进口商品仓库
|
|
|
IsFerme int `json:"isFerme"` //是否包税
|
|
|
HasCoin bool `json:"hasCoin"` //是否支持瑞币抵扣
|
|
|
HasBalance bool `json:"hasBalance"` //是否支持余额支付
|
|
|
Living live `json:"living"` //直播中
|
|
|
GysId uint `json:"gys_id"` //供应商id
|
|
|
SpecIcon []string `json:"spec_icon"` //特卖活动图标数组
|
|
|
CountryIcon string `json:"country_icon"` //进口国家图标
|
|
|
SecKill SecKillDetail `json:"sec_kill"`
|
|
|
SalePrice decimal.Decimal `json:"sale_price"`
|
|
|
}
|
|
|
|
|
|
// QueryGoodsListByComprehension 综合排序
|
|
|
func QueryGoodsListByComprehension(c *gin.Context) {
|
|
|
var p queryOrderGoodsListParam
|
|
|
if err := tools.ParseParams(&p, c); err != nil {
|
|
|
back.Fail(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
if p.SecondCategoryID == 0 && p.BrandID == 0 && len(p.Keyword) == 0 && p.ActivityID == 0 {
|
|
|
back.Fail(c, "参数不全")
|
|
|
return
|
|
|
}
|
|
|
//新增模块:存入用户的搜索记录
|
|
|
if p.UserId != 0 && p.Keyword != "" { //条件:用户id和关键词非空
|
|
|
var kw = keywords.RecookUserKeywordsModel{
|
|
|
UserId: p.UserId,
|
|
|
Keywords: p.Keyword,
|
|
|
CreatedTime: formatime.NewSecondNow(),
|
|
|
}
|
|
|
dbc.DB.Table(kw.TableName()).Create(&kw)
|
|
|
}
|
|
|
|
|
|
var goodsList []goods.Information
|
|
|
status := 1
|
|
|
if p.IsSale {
|
|
|
status = 0
|
|
|
}
|
|
|
q3 := mysql2.Db.Table("recook_goods_info as a").Where("is_virtual = 0").Where(goods.Information{
|
|
|
BrandID: p.BrandID,
|
|
|
SecondCategoryID: p.SecondCategoryID,
|
|
|
PublishStatus: uint(status),
|
|
|
})
|
|
|
if p.ActivityID != 0 {
|
|
|
// 批发活动id
|
|
|
sub := mysql2.Db.Table((&ac2.ActivityGoods{}).TableName()).Order("id desc").Select("goods_id").Where("activity_id = ?", p.ActivityID)
|
|
|
ids := make([]uint, 0)
|
|
|
sub.Pluck("goods_id", &ids)
|
|
|
q3 = q3.Clauses(clause.OrderBy{
|
|
|
Expression: clause.Expr{SQL: "FIELD(id,?)", Vars: []interface{}{ids}, WithoutParentheses: true}})
|
|
|
q3 = q3.Where("id in (?) and sale_publish = 1 and is_sale = 1", ids)
|
|
|
}
|
|
|
filters := map[string]interface{}{}
|
|
|
if p.SecondCategoryID > 0 {
|
|
|
filters["brand_id"] = p.BrandID
|
|
|
}
|
|
|
if p.SecondCategoryID > 0 {
|
|
|
filters["second_category_id"] = p.SecondCategoryID
|
|
|
}
|
|
|
findByKeyWord(q3, p.Keyword, filters, &goodsList, p.Page, p.IsSale, false)
|
|
|
back.Suc(c, "", GetGoodsRespByInfoList(goodsList, p.UserId, p.IsSale))
|
|
|
}
|
|
|
|
|
|
func findByKeyWord(q *gorm2.DB, str string, filters map[string]interface{}, data *[]goods.Information, page uint, isSale bool, isCondition bool) {
|
|
|
if str != "" {
|
|
|
gl, _, _ := search_ali.SearchByAliES(str, filters, isSale, 20, int(page))
|
|
|
q = q.Where("a.id in (?)", gl)
|
|
|
if !isCondition {
|
|
|
q = q.Clauses(clause.OrderBy{
|
|
|
Expression: clause.Expr{SQL: "FIELD(id,?)", Vars: []interface{}{gl}, WithoutParentheses: true}})
|
|
|
}
|
|
|
q.Find(&data)
|
|
|
} else {
|
|
|
q.Limit(20).Offset(int(page * 20)).Find(&data)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
type DescVolGoodsList []goods.Information
|
|
|
|
|
|
func (d DescVolGoodsList) Len() int { return len(d) }
|
|
|
func (d DescVolGoodsList) Less(i, j int) bool { return d[i].SalesVolume > d[j].SalesVolume }
|
|
|
func (d DescVolGoodsList) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
|
|
|
|
|
|
type AscVolGoodsList []goods.Information
|
|
|
|
|
|
func (d AscVolGoodsList) Len() int { return len(d) }
|
|
|
func (d AscVolGoodsList) Less(i, j int) bool { return d[i].SalesVolume < d[j].SalesVolume }
|
|
|
func (d AscVolGoodsList) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
|
|
|
|
|
|
// QueryGoodsListBySalesVolume 新的按照销量排序
|
|
|
func QueryGoodsListBySalesVolume(c *gin.Context) {
|
|
|
var p queryOrderGoodsListParam
|
|
|
if err := tools.ParseParams(&p, c); err != nil {
|
|
|
back.Fail(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if p.SecondCategoryID == 0 && p.BrandID == 0 && len(p.Keyword) == 0 && p.ActivityID == 0 {
|
|
|
back.Fail(c, "参数不全")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
status := 1
|
|
|
if p.IsSale {
|
|
|
status = 0
|
|
|
}
|
|
|
var goodsList []goods.Information
|
|
|
order := fmt.Sprintf("vol %s, id desc", p.Order)
|
|
|
q3 := mysql2.Db.Select("a.*, b.vol").Table("recook_goods_info as a").Where("is_virtual = 0").Joins("JOIN (SELECT goods_id, sum(sales_volume + sales_volume_inc ) as vol FROM recook_goods_sku GROUP BY goods_id) as b on a.id = b.goods_id ").Order(order).Where(goods.Information{
|
|
|
BrandID: p.BrandID,
|
|
|
SecondCategoryID: p.SecondCategoryID,
|
|
|
PublishStatus: uint(status),
|
|
|
Country: p.CountryId,
|
|
|
})
|
|
|
if p.ActivityID != 0 {
|
|
|
// 批发活动id
|
|
|
sub := mysql2.Db.Table((&ac2.ActivityGoods{}).TableName()).Select("goods_id").Where("activity_id = ?", p.ActivityID)
|
|
|
q3 = q3.Where("id in (?) and sale_publish = 1 and is_sale = 1", sub)
|
|
|
}
|
|
|
filters := map[string]interface{}{}
|
|
|
if p.SecondCategoryID > 0 {
|
|
|
filters["brand_id"] = p.BrandID
|
|
|
}
|
|
|
if p.SecondCategoryID > 0 {
|
|
|
filters["second_category_id"] = p.SecondCategoryID
|
|
|
}
|
|
|
findByKeyWord(q3, p.Keyword, filters, &goodsList, p.Page, p.IsSale, true)
|
|
|
back.Suc(c, "", GetGoodsRespByInfoList(goodsList, p.UserId, p.IsSale))
|
|
|
}
|
|
|
|
|
|
func QueryGoodsListByDiscountPrice(c *gin.Context) {
|
|
|
var p queryOrderGoodsListParam
|
|
|
if err := tools.ParseParams(&p, c); err != nil {
|
|
|
back.Fail(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if p.SecondCategoryID == 0 && p.BrandID == 0 && len(p.Keyword) == 0 && p.ActivityID == 0 {
|
|
|
back.Fail(c, "参数不全")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
status := 1
|
|
|
orderStr := "discount_price"
|
|
|
if p.IsSale {
|
|
|
status = 0
|
|
|
orderStr = "sale_purchase_price"
|
|
|
}
|
|
|
|
|
|
var goodsList []goods.Information
|
|
|
order := fmt.Sprintf("vol %s, id desc", p.Order)
|
|
|
q3 := mysql2.Db.Select("a.*, b.vol").Table("recook_goods_info as a").Where("is_virtual = 0").Joins(fmt.Sprintf("JOIN (SELECT goods_id, MIN(%s) as vol FROM recook_goods_sku GROUP BY goods_id) as b on a.id = b.goods_id", orderStr)).Order(order).Where(goods.Information{
|
|
|
BrandID: p.BrandID,
|
|
|
SecondCategoryID: p.SecondCategoryID,
|
|
|
PublishStatus: uint(status),
|
|
|
Country: p.CountryId,
|
|
|
})
|
|
|
|
|
|
if p.ActivityID != 0 {
|
|
|
// 批发活动id
|
|
|
sub := mysql2.Db.Table((&ac2.ActivityGoods{}).TableName()).Select("goods_id").Where("activity_id = ?", p.ActivityID)
|
|
|
q3 = q3.Where("id in (?) and sale_publish = 1 and is_sale= 1", sub)
|
|
|
}
|
|
|
|
|
|
filters := map[string]interface{}{}
|
|
|
if p.SecondCategoryID > 0 {
|
|
|
filters["brand_id"] = p.BrandID
|
|
|
}
|
|
|
if p.SecondCategoryID > 0 {
|
|
|
filters["second_category_id"] = p.SecondCategoryID
|
|
|
}
|
|
|
findByKeyWord(q3, p.Keyword, filters, &goodsList, p.Page, p.IsSale, true)
|
|
|
back.Suc(c, "", GetGoodsRespByInfoList(goodsList, p.UserId, p.IsSale))
|
|
|
}
|
|
|
|
|
|
// GetGoodsRespByInfoList ==============================================================
|
|
|
func GetGoodsRespByInfoList(goodsList []goods.Information, userID uint, isSale bool) []QueryCategoryGoodsListResp {
|
|
|
ids := make([]uint, 0)
|
|
|
bids := make([]uint, 0)
|
|
|
for _, v := range goodsList {
|
|
|
ids = append(ids, v.ID)
|
|
|
bids = append(bids, v.BrandID)
|
|
|
}
|
|
|
list := make([]QueryCategoryGoodsListResp, 0)
|
|
|
var u user.RecookUserInfoModel
|
|
|
mysql2.Db.First(&u, "id = ?", userID)
|
|
|
|
|
|
var sku []goods.Sku
|
|
|
mysql2.Db.Select(
|
|
|
"MIN(name), "+
|
|
|
"goods_id, "+
|
|
|
"SUM(inventory) AS inventory, "+
|
|
|
"SUM(sales_volume) AS sales_volume, "+
|
|
|
"SUM(sales_volume_inc) AS sales_volume_inc, "+
|
|
|
"SUM(sale_volume2) AS sale_volume2, "+
|
|
|
"SUM(sale_volume_inc2) AS sale_volume_inc2, "+
|
|
|
"MIN(purchase_price) AS purchase_price,"+
|
|
|
"MIN(original_price) AS original_price, "+
|
|
|
"MIN(discount_price) AS discount_price, "+
|
|
|
"MIN(commission) AS commission,"+
|
|
|
"MIN(coupon) AS coupon, "+
|
|
|
"MIN(sale_purchase_price) AS sale_purchase_price, "+
|
|
|
"MIN(extra_price) AS extra_price, "+
|
|
|
"MIN(sale_extra_price) AS sale_extra_price").
|
|
|
Group("goods_id").
|
|
|
Where("goods_id in (?)", ids).
|
|
|
Find(&sku)
|
|
|
skuMap := make(map[uint]goods.Sku)
|
|
|
for _, v := range sku {
|
|
|
skuMap[v.GoodsID] = v
|
|
|
}
|
|
|
var mainPhotoList []goods.MainPhoto
|
|
|
mysql2.Db.Find(&mainPhotoList, "goods_id in (?) AND is_master = 1", ids)
|
|
|
|
|
|
mpMap := make(map[uint]goods.MainPhoto)
|
|
|
for _, v := range mainPhotoList {
|
|
|
mpMap[v.GoodsID] = v
|
|
|
}
|
|
|
|
|
|
var brandList []goods.Brand
|
|
|
mysql2.Db.Find(&brandList, "id in (?)", bids)
|
|
|
brandMap := make(map[uint]goods.Brand)
|
|
|
for _, v := range brandList {
|
|
|
brandMap[v.ID] = v
|
|
|
}
|
|
|
//国家图标放入map结束
|
|
|
for _, v := range goodsList {
|
|
|
if isSale && v.SalePublish != 1 {
|
|
|
continue
|
|
|
}
|
|
|
if !isSale && v.PublishStatus == 0 {
|
|
|
continue
|
|
|
}
|
|
|
ss := skuMap[v.ID]
|
|
|
mp := mpMap[v.ID]
|
|
|
brand := brandMap[v.BrandID]
|
|
|
|
|
|
var startTime = formatime.Second{}
|
|
|
var endTime = formatime.Second{}
|
|
|
|
|
|
inventory := ss.Inventory
|
|
|
salesVolume := ss.SalesVolume + ss.SalesVolumeInc
|
|
|
if isSale {
|
|
|
salesVolume = ss.SaleVolume2 + ss.SaleVolumeInc2
|
|
|
}
|
|
|
commission := ss.GetSelfProfit(u.Level)
|
|
|
tags := make([]string, 0)
|
|
|
|
|
|
recookGoodsInfoModel := &goods2.RecookGoodsInfoModel{}
|
|
|
space := " "
|
|
|
list = append(list, QueryCategoryGoodsListResp{
|
|
|
ID: v.ID,
|
|
|
GoodsName: strings.Join([]string{v.GoodsName, strings.Replace(ss.Name, "+", space, -1)}, space),
|
|
|
BrandName: brand.Name + "品牌馆",
|
|
|
BrandImg: brand.LogoURL,
|
|
|
BrandId: brand.ID,
|
|
|
Description: v.Description,
|
|
|
Inventory: inventory,
|
|
|
SalesVolume: salesVolume,
|
|
|
MainPhotoURL: mp.URL,
|
|
|
PromotionName: "",
|
|
|
OriginalPrice: ss.OriginalPrice,
|
|
|
DiscountPrice: ss.DiscountPrice,
|
|
|
Commission: commission,
|
|
|
Tags: tags,
|
|
|
Percent: 0, //百分比,-1不显示
|
|
|
StartTime: startTime,
|
|
|
EndTime: endTime,
|
|
|
Coupon: ss.Coupon,
|
|
|
IsImport: v.IsImport,
|
|
|
Storehouse: v.Storehouse,
|
|
|
IsFerme: v.IsFerme,
|
|
|
HasCoin: recookGoodsInfoModel.HasCoin(v.Storehouse),
|
|
|
HasBalance: recookGoodsInfoModel.HasBalance(v.Storehouse),
|
|
|
GysId: v.VendorID,
|
|
|
CountryIcon: "",
|
|
|
SalePrice: ss.GetSalePrice(u.Level),
|
|
|
})
|
|
|
|
|
|
}
|
|
|
return list
|
|
|
}
|
|
|
|
|
|
type live struct {
|
|
|
Status int `json:"status"`
|
|
|
RoomId int `json:"room_id"`
|
|
|
}
|
|
|
|
|
|
//func GetGoodsRespBySkuList(skuList []goods.Sku, uid uint, isSale bool) []QueryCategoryGoodsListResp {
|
|
|
// list := make([]QueryCategoryGoodsListResp, 0, 0)
|
|
|
// var u user.RecookUserInfoModel
|
|
|
// mysql2.Db.First(&u, "id = ?", uid)
|
|
|
//
|
|
|
// rate1 := decimal.Zero
|
|
|
// rate2 := decimal.Zero
|
|
|
// rate3 := decimal.Zero
|
|
|
// if u.Level == 1 {
|
|
|
// rate1 = decimal.NewFromFloat32(0.4)
|
|
|
// rate2 = decimal.NewFromFloat32(0.1)
|
|
|
// }
|
|
|
// if u.Level == 2 {
|
|
|
// rate1 = decimal.NewFromFloat32(0.4)
|
|
|
// rate2 = decimal.NewFromFloat32(0.1)
|
|
|
// rate3 = decimal.NewFromFloat32(0.2)
|
|
|
// }
|
|
|
//
|
|
|
// for _, v := range skuList {
|
|
|
// var mainPhoto goods.MainPhoto
|
|
|
// dbc.DB.Select("url").First(&mainPhoto, "goods_id = ? AND is_master = 1", v.GoodsID)
|
|
|
//
|
|
|
// var goodsInfo goods.Information
|
|
|
// dbc.DB.First(&goodsInfo, v.GoodsID)
|
|
|
// if !isSale && goodsInfo.PublishStatus == 0 {
|
|
|
// continue
|
|
|
// }
|
|
|
// if isSale && goodsInfo.SalePublish == 0 {
|
|
|
// continue
|
|
|
// }
|
|
|
// gb := goods.Brand{}
|
|
|
// dbc.DB.First(&gb, "id = ?", goodsInfo.BrandID)
|
|
|
//
|
|
|
// var inventory uint
|
|
|
// //var percent uint
|
|
|
//
|
|
|
// var startTime = formatime.Second{}
|
|
|
// var endTime = formatime.Second{}
|
|
|
//
|
|
|
// salesVolume := v.SalesVolume + v.SalesVolumeInc
|
|
|
// discountPrice := v.DiscountPrice
|
|
|
// commission := v.Commission
|
|
|
// inventory = v.Inventory //sku库存
|
|
|
//
|
|
|
// base := v.GetBase()
|
|
|
// commission1 := base.Mul(rate1).Round(2)
|
|
|
// commission2 := base.Mul(rate2).Round(2)
|
|
|
// commission3 := base.Mul(rate3).Round(2)
|
|
|
// fmt.Println(commission1, commission2, commission3, base, v.PurchasePrice, v.DiscountPrice)
|
|
|
// commission = commission1.Add(commission2).Add(commission3)
|
|
|
//
|
|
|
// if u.Level == 10 {
|
|
|
// commission = v.DiscountPrice.Sub(v.PurchasePrice.Mul(decimal.NewFromFloat(1.03))).Mul(decimal.NewFromFloat(define.Coefficient)).Round(2)
|
|
|
// }
|
|
|
//
|
|
|
// recookGoodsInfoModel := &goods2.RecookGoodsInfoModel{}
|
|
|
// list = append(list, QueryCategoryGoodsListResp{
|
|
|
// ID: v.GoodsID,
|
|
|
// GoodsName: goodsInfo.GoodsName,
|
|
|
// BrandImg: gb.LogoURL,
|
|
|
// BrandName: gb.Name + "品牌馆",
|
|
|
// BrandId: gb.ID,
|
|
|
// Description: goodsInfo.Description,
|
|
|
// Inventory: inventory,
|
|
|
// SalesVolume: salesVolume,
|
|
|
// MainPhotoURL: mainPhoto.URL,
|
|
|
// PromotionName: "",
|
|
|
// OriginalPrice: v.OriginalPrice,
|
|
|
// DiscountPrice: discountPrice,
|
|
|
// Commission: commission,
|
|
|
// Percent: 0, //百分比,-1不显示
|
|
|
// StartTime: startTime,
|
|
|
// EndTime: endTime,
|
|
|
// Coupon: v.Coupon,
|
|
|
// IsImport: goodsInfo.IsImport,
|
|
|
// Storehouse: goodsInfo.Storehouse,
|
|
|
// IsFerme: goodsInfo.IsFerme,
|
|
|
// HasCoin: recookGoodsInfoModel.HasCoin(goodsInfo.Storehouse),
|
|
|
// HasBalance: recookGoodsInfoModel.HasBalance(goodsInfo.Storehouse),
|
|
|
// GysId: goodsInfo.VendorID,
|
|
|
// CountryIcon: "",
|
|
|
// SalePrice: v.GetSalePrice(u.Level),
|
|
|
// })
|
|
|
// }
|
|
|
// return list
|
|
|
//}
|
|
|
|
|
|
func GetListByLive(goodsList []goods.Information, userID uint, isSale bool) []QueryCategoryGoodsListResp {
|
|
|
return GetGoodsRespByInfoList(goodsList, userID, isSale)
|
|
|
}
|
|
|
|
|
|
func KeyWordEs(c *gin.Context) {
|
|
|
var p queryOrderGoodsListParam
|
|
|
if err := tools.ParseParams(&p, c); err != nil {
|
|
|
back.Fail(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
r := es.IKReq{
|
|
|
Text: p.Keyword,
|
|
|
Tokenizer: "ik_smart",
|
|
|
}
|
|
|
|
|
|
res := es.GetIK(r)
|
|
|
|
|
|
back.Suc(c, "", res.Tokens)
|
|
|
|
|
|
}
|