package goods import ( "fmt" "recook/internal/back" "recook/internal/dbc" "recook/internal/define" "recook/internal/model/attention" "recook/internal/model/coupon" "recook/internal/model/goods" "recook/internal/model/promotion" "recook/internal/model/shopping_trolley" goods2 "recook/internal/v2/model/recook/goods" "recook/internal/v2/model/recook/user" "recook/tools" "time" mysql2 "git.oa00.com/go/mysql" "github.com/gin-gonic/gin" "github.com/golangkit/formatime" "github.com/jinzhu/gorm" "github.com/shopspring/decimal" ) type summaryParam struct { UserID uint `json:"userID"` GoodsID int64 `json:"goodsID" validate:"required"` IsSale bool `json:"is_sale"` } type detailParam struct { UserID uint `json:"userId"` GoodsID int64 `json:"goodsID" validate:"required"` } type copyParam struct { UserID uint `json:"userId"` GoodsID uint `json:"goodsID" validate:"required"` } type evaluationSub struct { Total uint `gorm:"column:total" json:"total"` Children []goods.Evaluation `gorm:"column:children" json:"children"` } type attributeSub struct { Name string `gorm:"column:name" json:"name"` Children []goods.Attribute `gorm:"column:children" json:"children"` } type priceBorderSub struct { Min priceSub `json:"min"` Max priceSub `json:"max"` } type priceSub struct { OriginalPrice decimal.Decimal `gorm:"column:original_price" json:"originalPrice"` // 重新计算折扣价 DiscountPrice decimal.Decimal `gorm:"column:discount_price" json:"discountPrice"` Commission decimal.Decimal `gorm:"column:commission" json:"commission"` Ferme decimal.Decimal `json:"ferme"` } type allPrice struct { OriginalPrice decimal.Decimal `gorm:"column:original_price" json:"originalPrice"` // 重新计算折扣价 DiscountPrice decimal.Decimal `gorm:"column:discount_price" json:"discountPrice"` Commission decimal.Decimal `gorm:"column:commission" json:"commission"` PurchasePrice decimal.Decimal `gorm:"column:purchase_price" json:"purchasePrice"` Min uint `gorm:"column:min_num" json:"min"` Limit uint `gorm:"column:limit_num" json:"limit"` } type recommend struct { GoodsName string `json:"goodsName,omitempty"` GoodsId uint `json:"goodsId,omitempty"` Price string `json:"price"` MainPhotoURL string `json:"mainPhotoUrl"` } type summaryResponseNew struct { goods.Information Inventory uint `gorm:"column:inventory" json:"inventory"` SalesVolume uint `gorm:"column:sales_volume" json:"salesVolume"` SaleInventory uint `json:"sale_inventory"` Price priceBorderSub `json:"price"` Video *goods.Video `json:"video"` Recommends []recommend `json:"recommends"` MainPhotos []goods.MainPhoto `gorm:"column:mainPhotos" json:"mainPhotos"` Attributes []attributeSub `gorm:"column:attributes" json:"attributes"` Sku []goods.Sku `gorm:"column:sku" json:"sku"` Promotion *promotion.Goods `gorm:"column:promotion" json:"promotion"` Brand goods.Brand `gorm:"column:brand" json:"brand"` Evaluations evaluationSub `gorm:"column:evaluations" json:"evaluations"` Coupons []coupon.Information `gorm:"column:coupons" json:"coupons"` IsFavorite bool `json:"isFavorite"` ShoppingTrolleyCount int64 `gorm:"column:shopping_trolley_count" json:"shoppingTrolleyCount"` Notice noticeNew `json:"notice"` IsAllow bool `json:"isAllow"` CountryIcon string `json:"country_icon"` Live live `json:"living"` SecKill SecKillDetail `json:"sec_kill"` } type SecKillDetail struct { SecKill uint `json:"sec_kill"` SecKillEndTime string `json:"sec_kill_end_time"` SecKillMinPrice decimal.Decimal `json:"sec_kill_min_price"` SecKillCommission decimal.Decimal `json:"sec_kill_commission"` RealStock decimal.Decimal `json:"real_stock"` } type Notice struct { Title string `json:"title"` Img string `json:"img"` Type int `json:"type"` } type noticeNew struct { Title string `json:"title"` Img []string `json:"img"` Type int `json:"type"` } type momentsCopyResponse struct { goods.MomentsCopy IsAttention bool `json:"isAttention"` IsOfficial bool `json:"isOfficial"` Photos []goods.MomentsCopyPhoto `json:"photos"` Goods Goods `json:"goods"` } type salesInventory struct { Inventory uint `gorm:"column:inventory" json:"inventory"` SalesVolume uint `gorm:"column:sales_volume" json:"salesVolume"` SaleInventory uint `gorm:"column:sale_inventory" json:"sale_inventory"` } type Goods struct { ID uint `json:"id"` MainPhotoURL string `json:"mainPhotoURL"` Name string `json:"name"` Price decimal.Decimal `json:"price"` } func fetchRecommends(goodsId int64, brandId uint) []recommend { var goodsList []goods.Information sql := fmt.Sprintf(" SELECT `id`,`goods_name` FROM `recook_goods_info` WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM `recook_goods_info` WHERE brand_id = %d))) ORDER BY id LIMIT 7;", brandId) dbc.DB.Raw(sql).Scan(&goodsList) list := make([]recommend, 0, 0) for _, v := range goodsList { if v.ID == uint(goodsId) { continue } var mainPhoto goods.MainPhoto dbc.DB.First(&mainPhoto, "goods_id = ? AND is_master = 1", v.ID) var minAllPrice allPrice selectMinPriceStr := "MIN(discount_price) AS discount_price" dbc.DB.Table((&goods.Sku{}).TableName()).Select(selectMinPriceStr).First(&minAllPrice, "goods_id = ?", v.ID) price := minAllPrice.DiscountPrice var promotionGoods promotion.Goods dbc.DB.Select("id"). First(&promotionGoods, "goods_id = ? AND start_time <= ? AND end_time >= ?", v.ID, time.Now(), time.Now()) if promotionGoods.ID == 0 { dbc.DB.Select("id"). First(&promotionGoods, "goods_id = ? AND start_time >= ?", v.ID, time.Now()) } if promotionGoods.ID > 0 { var minPromSku promotion.Sku dbc.DB.Select("MIN(discount_price) AS discount_price, MIN(commission) AS commission").First(&minPromSku, "promotion_goods_id = ?", promotionGoods.ID) price = minPromSku.DiscountPrice } if len(list) < 6 { list = append(list, recommend{ GoodsName: v.GoodsName, GoodsId: v.ID, Price: price.String(), MainPhotoURL: mainPhoto.URL, }) } else { break } } return list } type DetailImg struct { List []goods.DetailPhoto `json:"list"` Brand goods.Brand `json:"brand"` } func QueryGoodsPhotosDetail(c *gin.Context) { var p detailParam err := tools.ParseParams(&p, c) if err != nil { back.Fail(c, err.Error()) return } var list []goods.DetailPhoto err = dbc.DB.Order("order_no asc").Find(&list, "goods_id = ?", p.GoodsID).Error if err != nil && gorm.IsRecordNotFoundError(err) { back.Err(c, err.Error()) return } //获取品牌数据 var info goods.Information err = dbc.DB.First(&info, "id= ?", p.GoodsID).Error if err != nil && gorm.IsRecordNotFoundError(err) { back.Err(c, err.Error()) return } var brand goods.Brand err = dbc.DB.First(&brand, "id= ?", info.BrandID).Error if err != nil && gorm.IsRecordNotFoundError(err) { back.Err(c, err.Error()) return } var gd = DetailImg{ List: list, Brand: brand, } back.Suc(c, "操作成功", &gd) } func QueryGoodsMomentsCopy(c *gin.Context) { var p copyParam err := tools.ParseParams(&p, c) if err != nil { back.Fail(c, err.Error()) return } list := make([]momentsCopyResponse, 0) dbc.DB.Table((&goods.MomentsCopy{}).TableName()).Find(&list, "goods_id = ? AND reviewing = 0", p.GoodsID) if len(list) > 0 { var g goods.Information dbc.DB.Select("goods_name").First(&g, p.GoodsID) var mainPhoto goods.MainPhoto dbc.DB.Select("url").First(&mainPhoto, "goods_id = ? AND is_master = 1", p.GoodsID) var sku goods.Sku dbc.DB.Select("goods_id, MIN(discount_price) AS discount_price").Find(&sku, "goods_id = ?", p.GoodsID).Group("goods_id") for i, v := range list { if p.UserID > 0 { var one attention.Info dbc.DB.First(&one, "user_id = ? AND follow_id = ?", p.UserID, list[i].UserID) if one.ID > 0 { list[i].IsAttention = true } } if v.UserID == 0 { list[i].IsOfficial = true } dbc.DB.Table((&goods.MomentsCopyPhoto{}).TableName()).Find(&(list[i].Photos), "moments_copy_id = ?", list[i].ID) list[i].Goods = Goods{ ID: p.GoodsID, MainPhotoURL: mainPhoto.URL, Name: g.GoodsName, Price: sku.DiscountPrice, } } } back.Suc(c, "操作成功", &list) } func QueryGoodsDetailNew(c *gin.Context) { var p summaryParam err := tools.ParseParams(&p, c) if err != nil { back.Fail(c, err.Error()) return } var u1 user.RecookUserInfoModel mysql2.Db.Find(&u1, "id = ?", p.UserID) rate1 := decimal.Zero rate2 := decimal.Zero rate3 := decimal.Zero if u1.Level == 1 { rate1 = decimal.NewFromFloat32(0.4) rate2 = decimal.NewFromFloat32(0.1) } if u1.Level == 2 { rate1 = decimal.NewFromFloat32(0.4) rate2 = decimal.NewFromFloat32(0.1) rate3 = decimal.NewFromFloat(0.2) } var summary summaryResponseNew dbc.DB.Table((&goods.Information{}).TableName()).First(&summary, p.GoodsID) var sv salesInventory dbc.DB.Table((&goods.Sku{}).TableName()).Select("SUM(inventory) AS inventory, SUM(sales_volume) AS sales_volume, SUM(sale_inventory) AS sale_inventory"). First(&sv, "goods_id = ?", p.GoodsID) summary.SalesVolume = sv.SalesVolume summary.Inventory = sv.Inventory summary.SaleInventory = sv.SaleInventory var minAllPrice allPrice selectMinPriceStr := "MIN(original_price) AS original_price, " + "MIN(discount_price) AS discount_price, " + "MIN(commission) AS commission, " + "MIN(purchase_price) AS purchase_price " + "MIN(min_num) AS min " + "MIN(limit_num) AS limit " dbc.DB.Table((&goods.Sku{}).TableName()).Select(selectMinPriceStr).First(&minAllPrice, "goods_id = ?", p.GoodsID) var maxAllPrice allPrice selectMaxPriceStr := "MAX(original_price) AS original_price, " + "MAX(discount_price) AS discount_price, " + "MAX(commission) AS commission, " + "MAX(purchase_price) AS purchase_price " + "MAX(min_num) AS min " + "MAX(limit_num) AS limit " dbc.DB.Table((&goods.Sku{}).TableName()).Select(selectMaxPriceStr).First(&maxAllPrice, "goods_id = ?", p.GoodsID) minCost := minAllPrice.PurchasePrice.Mul(decimal.NewFromFloat(1.03)) minbase := minAllPrice.DiscountPrice.Sub(minCost).Mul(decimal.NewFromFloat(define.Coefficient)).Round(2) minCommission1 := minbase.Mul(rate1).Round(2) minCommission2 := minbase.Mul(rate2).Round(2) minCommission3 := minbase.Mul(rate3).Round(2) maxbase := maxAllPrice.DiscountPrice.Sub(minCost).Mul(decimal.NewFromFloat(define.Coefficient)).Round(2) maxCommission1 := maxbase.Mul(rate1).Round(2) maxCommission2 := maxbase.Mul(rate2).Round(2) maxCommission3 := maxbase.Mul(rate3).Round(2) summary.Price = priceBorderSub{ priceSub{ OriginalPrice: minAllPrice.OriginalPrice, DiscountPrice: minAllPrice.DiscountPrice, Commission: minCommission1.Add(minCommission2).Add(minCommission3), }, priceSub{ OriginalPrice: maxAllPrice.OriginalPrice, DiscountPrice: maxAllPrice.DiscountPrice, Commission: maxCommission1.Add(maxCommission2).Add(maxCommission3), }, } //if summary.IsFerme == goods2.RecookGoodsInfoIsFermeTrue { // summary.Price.Min.Ferme = minAllPrice.PurchasePrice.Mul(decimal.NewFromFloat(1.2)).Mul(decimal.NewFromFloat(0.091)).Truncate(2) // summary.Price.Max.Ferme = maxAllPrice.PurchasePrice.Mul(decimal.NewFromFloat(1.2)).Mul(decimal.NewFromFloat(0.091)).Truncate(2) //} if !p.IsSale { summary.Recommends = fetchRecommends(p.GoodsID, summary.BrandID) } var video goods.Video dbc.DB.Table((&goods.Video{}).TableName()).First(&(video), "goods_id = ?", p.GoodsID) if video.ID > 0 { summary.Video = &video } dbc.DB.Table((&goods.MainPhoto{}).TableName()).Order("order_no asc, is_master desc").Find(&(summary.MainPhotos), "goods_id = ? and is_master = 0", p.GoodsID) dbc.DB.Table((&goods.Sku{}).TableName()).Find(&(summary.Sku), "goods_id = ?", p.GoodsID) for index, v := range summary.Sku { skb := v.GetBase() sc1 := skb.Mul(rate1).Round(2) sc2 := skb.Mul(rate2).Round(2) sc3 := skb.Mul(rate3).Round(2) summary.Sku[index].Commission = sc1.Add(sc2).Add(sc3) } now := time.Now() var promotionGoods promotion.Goods dbc.DB.First(&promotionGoods, "goods_id = ? AND start_time <= ? AND end_time >= ?", p.GoodsID, now, now) if promotionGoods.ID == 0 { // dbc.DB.First(&promotionGoods, "goods_id = ? AND start_time >= ?", p.GoodsID, now) } var gc goods.Category dbc.DB.Table(gc.TableName()).First(&gc, "id = ?", summary.SecondCategoryID) summary.IsAllow = gc.IsAllow dbc.DB.Table((&goods.Brand{}).TableName()).First(&(summary.Brand), "id = ?", summary.BrandID) var brandGoodsCount uint // 品牌所有的商品种类数量, 需要过滤下架的类型 dbc.DB.Model(&goods.Information{}).Where("brand_id = ?", summary.BrandID).Where("publish_status = ?", 1).Count(&brandGoodsCount) summary.Brand.GoodsCount = brandGoodsCount //var country goods2.RecookAbroadCountryModel //dbc.DB.Table(country.TableName()).First(&country, "id = ?", summary.Country) //summary.CountryIcon = country.Icon //var vo live //dbc.DB.Table("recook_live_live_item").Where("main_goods_id=?", summary.ID).Select("status,id as item_id").Order("id desc").First(&vo) //summary.Live = live{ // Status: vo.Status, // RoomId: vo.RoomId, //} //dbc.DB.Table((&goods.Evaluation{}).TableName()).Where("goods_id = ? and pass=?", p.GoodsID, 1).Count(&(summary.Evaluations.Total)) //dbc.DB.Table((&goods.Evaluation{}).TableName()).Limit(5).Find(&(summary.Evaluations.Children), "goods_id = ? and pass=?", p.GoodsID, 1) dbc.DB.Table((&goods.Attribute{}).TableName()).Select("name").Group("name").Find(&(summary.Attributes), "goods_id = ?", p.GoodsID) for i, v := range summary.Attributes { dbc.DB.Table((&goods.Attribute{}).TableName()).Select("id, value").Find(&(summary.Attributes[i].Children), "goods_id = ? AND name = ?", p.GoodsID, v.Name) } // 找优惠券 //dbc.DB.Table((&coupon.Information{}).TableName()).Limit(2).Order("id desc").Find(&(summary.Coupons), "((scope = ?) OR (scope = ? AND brand_id = ?)) AND end_time > ?", define.CouponScopeUniversal, define.CouponScopeBrand, summary.BrandID, now) if p.UserID > 0 { var f goods.Favorites dbc.DB.First(&f, "user_id = ? AND goods_id = ?", p.UserID, p.GoodsID) summary.IsFavorite = f.ID > 0 type cnt struct { ShoppingTrolleyCount int64 `gorm:"column:shopping_trolley_count" json:"shoppingTrolleyCount"` } var cntStruct cnt dbc.DB.Table((&shopping_trolley.Information{}).TableName()).Select("SUM(quantity) AS shopping_trolley_count").Where("user_id = ?", p.UserID).First(&cntStruct) summary.ShoppingTrolleyCount = cntStruct.ShoppingTrolleyCount } recookGoodsNoticeGoodsModel := &goods2.RecookGoodsNoticeGoodsModel{} noticeGoods := recookGoodsNoticeGoodsModel.FindByGoodsId(summary.ID) if noticeGoods.Id > 0 { recookGoodsNoticeModel := &goods2.RecookGoodsNoticeModel{} noticeInfo := recookGoodsNoticeModel.FindById(noticeGoods.NoticeId) now := time.Now().Unix() var imgs []string dbc.DB.Table((&goods2.RecookGoodsNoticeImageModel{}).TableName()).Where("noticeId=?", noticeInfo.Id).Pluck("image", &imgs) if noticeInfo.Id > 0 && now > noticeInfo.StartTime.Time.Unix() && now < noticeInfo.EndTime.Time.Unix() { summary.Notice.Title = noticeInfo.Title summary.Notice.Img = imgs summary.Notice.Type = noticeInfo.Type } } back.Suc(c, "操作成功", &summary) rankings := goods.HotSellRankings{ GoodsId: uint(p.GoodsID), FirstCategoryID: summary.FirstCategoryID, SecondCategoryID: summary.SecondCategoryID, Date: formatime.NewDateNow(), } dbc.DB.FirstOrCreate(&rankings, "date = ? AND goods_id = ?", now.Format("2006-01-02"), p.GoodsID) dbc.DB.Model(&rankings).Updates(goods.HotSellRankings{ Clicks: rankings.Clicks + 1, }) dbc.DB.Table("recook_app_user_history").Create(&user.RecookAppUserHistory{ GoodsID: p.GoodsID, UserID: p.UserID, }) }