package goods import ( "fmt" "recook/internal/back" "recook/internal/cache" "recook/internal/dbc" "recook/internal/model/goods" "recook/internal/model/promotion" "recook/internal/v2/lib/es" "recook/internal/v2/model/flashsale" "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" "strconv" "strings" "time" mysql2 "git.oa00.com/go/mysql" "github.com/gin-gonic/gin" "github.com/golangkit/formatime" "github.com/shopspring/decimal" gorm2 "gorm.io/gorm" ) 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"` } 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"` } // 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 { 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 q3 := mysql2.Db.Table("recook_goods_info as a"). Order("id desc").Where(goods.Information{ BrandID: p.BrandID, SecondCategoryID: p.SecondCategoryID, PublishStatus: 1, Country: p.CountryId, }) findByKeyWord(q3, p.Keyword, &goodsList, p.Page) back.Suc(c, "", GetGoodsRespByInfoList(goodsList, p.UserId)) } func findByKeyWord(q *gorm2.DB, str string, data *[]goods.Information, page uint) { if str != "" { gl, _, _ := search_ali.SearchByAliES(str, 20, int(page)) q.Where("a.id in (?)", gl).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 { back.Fail(c, "参数不全") return } var goodsList []goods.Information order := fmt.Sprintf("sales_volume %s, id desc", p.Order) q3 := mysql2.Db.Table("recook_goods_info as a").Order(order).Where(goods.Information{ BrandID: p.BrandID, SecondCategoryID: p.SecondCategoryID, PublishStatus: 1, Country: p.CountryId, }) findByKeyWord(q3, p.Keyword, &goodsList, p.Page) back.Suc(c, "", GetGoodsRespByInfoList(goodsList, p.UserId)) } 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 { back.Fail(c, "参数不全") return } var goodsIdList []uint var goodsInfoIdList []goods.Information q3 := mysql2.Db.Table("recook_goods_info as a").Where(goods.Information{ BrandID: p.BrandID, SecondCategoryID: p.SecondCategoryID, PublishStatus: 1, Country: p.CountryId, }) findByKeyWord(q3, p.Keyword, &goodsInfoIdList, p.Page) for _, v := range goodsInfoIdList { goodsIdList = append(goodsIdList, v.ID) } var skuList []goods.Sku order := fmt.Sprintf("discount_price %s", p.Order) dbc.DB.Select("SUM(inventory) AS inventory, "+ "SUM(sales_volume) AS sales_volume, "+ "MIN(original_price) AS original_price, "+ "MIN(discount_price) AS discount_price, "+ "MIN(commission) AS commission, "+ "goods_id").Order(order).Group("goods_id"). Find(&skuList, "goods_id IN (?)", goodsIdList) back.Suc(c, "", GetGoodsRespBySkuList(skuList)) } // GetGoodsRespByInfoList ============================================================== func GetGoodsRespByInfoList(goodsList []goods.Information, userID uint) []QueryCategoryGoodsListResp { list := make([]QueryCategoryGoodsListResp, 0) var u user.RecookUserInfoModel mysql2.Db.First(&u, "id = ?", userID) //国家图标放入map结束 for _, v := range goodsList { var mainPhoto goods.MainPhoto dbc.DB.Select("url").First(&mainPhoto, "goods_id = ? AND is_master = 1", v.ID) gb := goods.Brand{} dbc.DB.First(&gb, "id = ?", v.BrandID) var sku goods.Sku mysql2.Db.Select( "MIN(name), "+ "SUM(inventory) AS inventory, "+ "SUM(sales_volume) AS sales_volume, "+ "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"). Where("goods_id = ?", v.ID). Group("goods_id"). Find(&sku) //var inventory uint //var percent uint var startTime = formatime.Second{} var endTime = formatime.Second{} inventory := sku.Inventory salesVolume := v.SalesVolume discountPrice := sku.DiscountPrice commission := sku.Commission tags := make([]string, 0) // 查看是否是 新人特惠 商品 if isMember, _ := cache.IsMemberOfNewerTehui(strconv.Itoa(int(v.ID))); isMember { tags = append(tags, "新人特惠") } rate1 := decimal.NewFromFloat32(0.4) rate2 := decimal.NewFromFloat32(0.1) rate3 := decimal.Zero if u.Level == 2 { rate3 = decimal.NewFromFloat(0.2) } base := sku.GetBase() commission1 := base.Mul(rate1).Round(2) commission2 := base.Mul(rate2).Round(2) commission3 := base.Mul(rate3).Round(2) commission = commission1.Add(commission2).Add(commission3) recookGoodsInfoModel := &goods2.RecookGoodsInfoModel{} space := " " list = append(list, QueryCategoryGoodsListResp{ ID: v.ID, GoodsName: strings.Join([]string{v.GoodsName, strings.Replace(sku.Name, "+", space, -1)}, space), BrandName: gb.Name + "品牌馆", BrandImg: gb.LogoURL, BrandId: gb.ID, Description: v.Description, Inventory: inventory, SalesVolume: salesVolume, MainPhotoURL: mainPhoto.URL, PromotionName: "", OriginalPrice: sku.OriginalPrice, DiscountPrice: discountPrice, Commission: commission, Tags: tags, Percent: 0, //百分比,-1不显示 StartTime: startTime, EndTime: endTime, Coupon: sku.Coupon, IsImport: v.IsImport, Storehouse: v.Storehouse, IsFerme: v.IsFerme, HasCoin: recookGoodsInfoModel.HasCoin(v.Storehouse), HasBalance: recookGoodsInfoModel.HasBalance(v.Storehouse), GysId: v.VendorID, CountryIcon: "", }) } return list } type live struct { Status int `json:"status"` RoomId int `json:"room_id"` } func GetGoodsRespBySkuList(skuList []goods.Sku) []QueryCategoryGoodsListResp { list := make([]QueryCategoryGoodsListResp, 0, 0) 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) 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 := goodsInfo.SalesVolume discountPrice := v.DiscountPrice commission := v.Commission inventory = v.Inventory //sku库存 now := time.Now() var promotionGoods promotion.Goods dbc.DB.Select("id, promotion_name, start_time, end_time"). First(&promotionGoods, "goods_id = ? AND start_time <= ? AND end_time >= ?", v.GoodsID, now, now) if promotionGoods.ID > 0 { var promotionSku promotion.Sku dbc.DB.Select("SUM(inventory) AS inventory, SUM(sales_volume) AS sales_volume,min(discount_price) as discount_price,min(discount_price) as discount_price"). First(&promotionSku, "promotion_goods_id = ?", promotionGoods.ID) discountPrice = promotionSku.DiscountPrice //活动的价格 commission = promotionSku.Commission //活动的佣金 inventory = promotionSku.Inventory salesVolume = promotionSku.SalesVolume //计算% //percent = uint(salesVolume / (inventory + salesVolume) * 100) startTime = promotionGoods.StartTime endTime = promotionGoods.EndTime } else { dbc.DB.Select("id, promotion_name"). First(&promotionGoods, "goods_id = ? AND start_time > ?", v.GoodsID, now) if promotionGoods.ID > 0 { var promotionSku promotion.Sku dbc.DB.Select("MIN(discount_price) AS discount_price, MIN(commission) AS commission").Find(&promotionSku, "promotion_goods_id = ?", promotionGoods.ID) startTime = promotionGoods.StartTime endTime = promotionGoods.EndTime } } //新增进口专区国家图标 //var iconList []goods2.RecookAbroadCountryModel //dbc.DB.Table((&goods2.RecookAbroadCountryModel{}).TableName()).Find(&iconList) //var countryMap = make(map[uint]string) //countryMap[0] = "" //for _, j := range iconList { // countryMap[j.ID] = j.Icon //} //fmt.Println(len(countryMap)) //国家图标放入map结束 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: promotionGoods.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: "", }) } return list } func GetListByLive(goodsList []goods.Information) []QueryCategoryGoodsListResp { //return GetGoodsRespByInfoList(goodsList) return nil } func secKillAbout(list []QueryCategoryGoodsListResp) (result []QueryCategoryGoodsListResp) { //新增秒杀的图标 //获取当前时间段的秒杀商品 now := time.Now() var seckill flashsale.RecookSecKillModel dbc.DB.Table(seckill.TableName()).Where("activity_start_time?", now).Where("status=2").First(&seckill) smp := GetSecKillGoods() fmt.Println(len(smp)) for i, v := range list { if _, ok := smp[v.ID]; ok { one := GetSecKillDetail(v.ID) list[i].SecKill = one } else { continue } } result = list return } func GetSecKillGoods() map[uint]uint { now := time.Now() var seckill flashsale.RecookSecKillModel dbc.DB.Table(seckill.TableName()).Where("activity_start_time?", now).Where("status=2").First(&seckill) //获取当前时间段的商品 now2 := time.Date(0, 1, 1, now.Hour(), now.Minute(), now.Second(), 0, time.Local) var sgal []int64 q := dbc.DB.Table((&flashsale.RecookSecKillSortModel{}).TableName()).Where("show_time_start?", now2).Where("sec_kill_activity_id=?", seckill.Id) q.Group("goods_id").Pluck("goods_id", &sgal) smp := make(map[uint]uint) for _, i2 := range sgal { smp[uint(i2)] = 1 } return smp } func GetSecKillDetail(gi uint) SecKillDetail { now := time.Now() var seckill flashsale.RecookSecKillModel dbc.DB.Table(seckill.TableName()).Where("activity_start_time?", now).Where("status=2").First(&seckill) var sk flashsale.RecookSecKillGoodsModel dbc.DB.Table(sk.TableName()).Where("sec_kill_activity_id=?", seckill.Id).Where("goods_id=?", gi).First(&sk) now2 := time.Date(0, 1, 1, now.Hour(), now.Minute(), now.Second(), 0, time.Local) secMinPrice := decimal.Zero secCommission := decimal.Zero MaxStock := decimal.Zero //sku_list var skuList []flashsale.RecookSecKillGoodsModel var sl []int q := dbc.DB.Table((&flashsale.RecookSecKillSortModel{}).TableName()).Where("show_time_start?", now2).Where("sec_kill_activity_id=?", sk.SecKillActivityId) q.Select("sku_id").Where("goods_id=?", sk.GoodsId).Pluck("sku_id", &sl) dbc.DB.Table(sk.TableName()).Where("sec_kill_activity_id=?", sk.SecKillActivityId).Where("goods_id=?", sk.GoodsId).Where("goods_sku_id in (?)", sl).Find(&skuList) secEndTime := time.Time{} for i1, model := range skuList { var sec flashsale.RecookSecKillSortModel q.Where("goods_id=?", sk.GoodsId).Where("sku_id=?", model.GoodsSkuId).First(&sec) if i1 == 0 { secMinPrice = model.SecKillDiscountPrice secCommission = model.SecKillCommission secEndTime = sec.ShowTimeEnd MaxStock = model.RealStock } else { if secMinPrice.GreaterThan(model.SecKillDiscountPrice) { secMinPrice = model.SecKillDiscountPrice } if secCommission.LessThan(model.SecKillCommission) { secCommission = model.SecKillCommission } if sec.ShowTimeEnd.After(secEndTime) { secEndTime = sec.ShowTimeEnd } if MaxStock.LessThan(model.RealStock) { MaxStock = model.RealStock } } } one := SecKillDetail{ SecKill: 1, SecKillEndTime: secEndTime.Format("15:04:05"), SecKillMinPrice: secMinPrice, SecKillCommission: secCommission, RealStock: MaxStock, } return one } 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) }