You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
761 lines
28 KiB
761 lines
28 KiB
4 years ago
|
package goods
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
mysql2 "git.oa00.com/go/mysql"
|
||
|
"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"
|
||
|
"recook/internal/v2/model/flashsale"
|
||
|
goods2 "recook/internal/v2/model/recook/goods"
|
||
|
"recook/internal/v2/model/recook/user"
|
||
|
"recook/tools"
|
||
|
"time"
|
||
|
|
||
|
"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"`
|
||
|
}
|
||
|
|
||
|
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"`
|
||
|
}
|
||
|
|
||
|
type recommend struct {
|
||
|
GoodsName string `json:"goodsName,omitempty"`
|
||
|
GoodsId uint `json:"goodsId,omitempty"`
|
||
|
Price string `json:"price"`
|
||
|
MainPhotoURL string `json:"mainPhotoUrl"`
|
||
|
}
|
||
|
|
||
|
type summaryResponse struct {
|
||
|
goods.Information
|
||
|
Inventory uint `gorm:"column:inventory" json:"inventory"`
|
||
|
SalesVolume uint `gorm:"column:sales_volume" json:"salesVolume"`
|
||
|
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 Notice `json:"notice"`
|
||
|
IsAllow bool `json:"isAllow"`
|
||
|
CountryIcon string `json:"country_icon"`
|
||
|
Live live `json:"living"`
|
||
|
SecKill SecKillDetail `json:"sec_kill"`
|
||
|
}
|
||
|
type summaryResponseNew struct {
|
||
|
goods.Information
|
||
|
Inventory uint `gorm:"column:inventory" json:"inventory"`
|
||
|
SalesVolume uint `gorm:"column:sales_volume" json:"salesVolume"`
|
||
|
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"`
|
||
|
}
|
||
|
|
||
|
type Goods struct {
|
||
|
ID uint `json:"id"`
|
||
|
MainPhotoURL string `json:"mainPhotoURL"`
|
||
|
Name string `json:"name"`
|
||
|
Price decimal.Decimal `json:"price"`
|
||
|
}
|
||
|
|
||
|
func QueryGoodsDetail(c *gin.Context) {
|
||
|
var p summaryParam
|
||
|
err := tools.ParseParams(&p, c)
|
||
|
if err != nil {
|
||
|
back.Fail(c, err.Error())
|
||
|
return
|
||
|
}
|
||
|
|
||
|
var summary summaryResponse
|
||
|
|
||
|
dbc.DB.Table((&goods.Information{}).TableName()).First(&summary, p.GoodsID)
|
||
|
///*
|
||
|
// 新增内容:商品下架则不显示
|
||
|
//*/
|
||
|
//if summary.PublishStatus == 0 {
|
||
|
// back.Fail(c, "您好,该商品已下架!")
|
||
|
// return
|
||
|
//}
|
||
|
|
||
|
var sv salesInventory
|
||
|
dbc.DB.Table((&goods.Sku{}).TableName()).Select("SUM(inventory) AS inventory, SUM(sales_volume) AS sales_volume").First(&sv, "goods_id = ?", p.GoodsID)
|
||
|
summary.SalesVolume = sv.SalesVolume
|
||
|
summary.Inventory = sv.Inventory
|
||
|
|
||
|
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 "
|
||
|
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 "
|
||
|
dbc.DB.Table((&goods.Sku{}).TableName()).Select(selectMaxPriceStr).First(&maxAllPrice, "goods_id = ?", p.GoodsID)
|
||
|
|
||
|
summary.Price = priceBorderSub{
|
||
|
priceSub{
|
||
|
OriginalPrice: minAllPrice.OriginalPrice,
|
||
|
DiscountPrice: minAllPrice.DiscountPrice,
|
||
|
Commission: minAllPrice.Commission,
|
||
|
},
|
||
|
priceSub{
|
||
|
OriginalPrice: maxAllPrice.OriginalPrice,
|
||
|
DiscountPrice: maxAllPrice.DiscountPrice,
|
||
|
Commission: maxAllPrice.Commission,
|
||
|
},
|
||
|
}
|
||
|
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)
|
||
|
}
|
||
|
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)
|
||
|
|
||
|
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)
|
||
|
}
|
||
|
|
||
|
// 排除活动商品的影响
|
||
|
// 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)
|
||
|
|
||
|
// var maxPromSku promotion.Sku
|
||
|
// dbc.DB.Select("MAX(discount_price) AS discount_price, MAX(commission) AS commission").First(&maxPromSku, "promotion_goods_id = ?", promotionGoods.ID)
|
||
|
|
||
|
// summary.Promotion = &promotionGoods
|
||
|
// summary.Price.Min.DiscountPrice = minPromSku.DiscountPrice
|
||
|
// summary.Price.Min.Commission = minPromSku.Commission
|
||
|
// summary.Price.Max.DiscountPrice = maxPromSku.DiscountPrice
|
||
|
// summary.Price.Max.Commission = maxPromSku.Commission
|
||
|
|
||
|
// summary.SalesVolume = 0
|
||
|
// summary.Inventory = 0
|
||
|
|
||
|
// var promotionSku []promotion.Sku
|
||
|
// dbc.DB.Find(&promotionSku, "promotion_goods_id = ?", promotionGoods.ID)
|
||
|
// for i1, v1 := range summary.Sku {
|
||
|
// for _, v2 := range promotionSku {
|
||
|
// if v1.ID == v2.SkuID {
|
||
|
// summary.Sku[i1].DiscountPrice = v2.DiscountPrice
|
||
|
// summary.Sku[i1].Inventory = v2.Inventory
|
||
|
// summary.Sku[i1].SalesVolume = v2.SalesVolume
|
||
|
// summary.Sku[i1].Commission = v2.Commission
|
||
|
// summary.SalesVolume += v2.SalesVolume
|
||
|
// summary.Inventory += v2.Inventory
|
||
|
// }
|
||
|
// }
|
||
|
// }
|
||
|
|
||
|
// summary.Description = promotionGoods.Subtitle
|
||
|
// }
|
||
|
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()
|
||
|
if noticeInfo.Id > 0 && now > noticeInfo.StartTime.Time.Unix() && now < noticeInfo.EndTime.Time.Unix() {
|
||
|
summary.Notice.Title = noticeInfo.Title
|
||
|
summary.Notice.Img = noticeInfo.Img
|
||
|
summary.Notice.Type = noticeInfo.Type
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//新增秒杀模块拦截判断
|
||
|
var seckill flashsale.RecookSecKillModel
|
||
|
mysql2.Db.Table(seckill.TableName()).Where("activity_start_time<?", now).Where("activity_end_time>?", now).Where("status=2").First(&seckill)
|
||
|
//获取当前时间段的商品
|
||
|
now2 := time.Date(0, 1, 1, now.Hour(), now.Minute(), now.Second(), 0, time.Local)
|
||
|
var secgoods []flashsale.RecookSecKillSortModel
|
||
|
mysql2.Db.Table((&flashsale.RecookSecKillSortModel{}).TableName()).Where("show_time_start<?", now2).Where("show_time_end>?", now2).Where("sec_kill_activity_id=?", seckill.Id).Where("goods_id=?", summary.ID).Find(&secgoods)
|
||
|
//若该商品在秒杀中,则,重新赋值
|
||
|
if len(secgoods) > 0 {
|
||
|
//秒杀价格
|
||
|
var mp = make(map[uint]flashsale.RecookSecKillGoodsModel)
|
||
|
var sl []flashsale.RecookSecKillGoodsModel
|
||
|
mysql2.Db.Table((&flashsale.RecookSecKillGoodsModel{}).TableName()).Where("sec_kill_activity_id=?", seckill.Id).Where("goods_id=?", summary.ID).Find(&sl)
|
||
|
for _, v := range sl {
|
||
|
mp[v.GoodsSkuId] = v
|
||
|
}
|
||
|
for i, sku := range summary.Sku {
|
||
|
if _, ok := mp[sku.ID]; ok {
|
||
|
summary.Sku[i].DiscountPrice = mp[sku.ID].SecKillDiscountPrice
|
||
|
summary.Sku[i].Commission = mp[sku.ID].SecKillDiscountPrice.Mul(mp[sku.ID].SecKillCommissionRate).Truncate(2)
|
||
|
} else {
|
||
|
summary.Sku[i] = goods.Sku{}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
summary.SecKill.SecKill = 1
|
||
|
summary.SecKill.SecKillEndTime = secgoods[0].ShowTimeEnd.Format("15:04:05")
|
||
|
var newsku []goods.Sku
|
||
|
minPrice := summary.Sku[0].DiscountPrice
|
||
|
maxCom := summary.Sku[0].Commission
|
||
|
for _, v := range summary.Sku {
|
||
|
if v.ID > 0 {
|
||
|
newsku = append(newsku, v)
|
||
|
if v.DiscountPrice.LessThan(minPrice) {
|
||
|
minPrice = v.DiscountPrice
|
||
|
}
|
||
|
if v.Commission.GreaterThan(maxCom) {
|
||
|
maxCom = v.Commission
|
||
|
}
|
||
|
} else {
|
||
|
continue
|
||
|
}
|
||
|
}
|
||
|
summary.SecKill.SecKillCommission = maxCom
|
||
|
summary.SecKill.SecKillMinPrice = minPrice
|
||
|
summary.Sku = newsku
|
||
|
for i, v := range summary.Attributes {
|
||
|
for i2, j := range v.Children {
|
||
|
if _, ok := mp[j.ID]; ok {
|
||
|
} else {
|
||
|
summary.Attributes[i].Children[i2] = goods.Attribute{}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
var newat []attributeSub
|
||
|
for _, v := range summary.Attributes {
|
||
|
var newattri []goods.Attribute
|
||
|
for _, j := range v.Children {
|
||
|
if j.ID > 0 {
|
||
|
newattri = append(newattri, j)
|
||
|
} else {
|
||
|
continue
|
||
|
}
|
||
|
}
|
||
|
newat = append(newat, attributeSub{
|
||
|
Name: v.Name,
|
||
|
Children: newattri,
|
||
|
})
|
||
|
}
|
||
|
summary.Attributes = newat
|
||
|
//判断结束
|
||
|
}
|
||
|
|
||
|
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,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
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 GoodsDetailImg 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 = GoodsDetailImg{
|
||
|
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 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").First(&sv, "goods_id = ?", p.GoodsID)
|
||
|
summary.SalesVolume = sv.SalesVolume
|
||
|
summary.Inventory = sv.Inventory
|
||
|
|
||
|
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 "
|
||
|
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 "
|
||
|
dbc.DB.Table((&goods.Sku{}).TableName()).Select(selectMaxPriceStr).First(&maxAllPrice, "goods_id = ?", p.GoodsID)
|
||
|
|
||
|
summary.Price = priceBorderSub{
|
||
|
priceSub{
|
||
|
OriginalPrice: minAllPrice.OriginalPrice,
|
||
|
DiscountPrice: minAllPrice.DiscountPrice,
|
||
|
Commission: minAllPrice.Commission,
|
||
|
},
|
||
|
priceSub{
|
||
|
OriginalPrice: maxAllPrice.OriginalPrice,
|
||
|
DiscountPrice: maxAllPrice.DiscountPrice,
|
||
|
Commission: maxAllPrice.Commission,
|
||
|
},
|
||
|
}
|
||
|
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)
|
||
|
}
|
||
|
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)
|
||
|
|
||
|
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
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//新增秒杀模块拦截判断
|
||
|
var seckill flashsale.RecookSecKillModel
|
||
|
mysql2.Db.Table(seckill.TableName()).Where("activity_start_time<?", now).Where("activity_end_time>?", now).Where("status=2").First(&seckill)
|
||
|
//获取当前时间段的商品
|
||
|
now2 := time.Date(0, 1, 1, now.Hour(), now.Minute(), now.Second(), 0, time.Local)
|
||
|
var secgoods []flashsale.RecookSecKillSortModel
|
||
|
mysql2.Db.Table((&flashsale.RecookSecKillSortModel{}).TableName()).Where("show_time_start<?", now2).Where("show_time_end>?", now2).Where("sec_kill_activity_id=?", seckill.Id).Where("goods_id=?", summary.ID).Find(&secgoods)
|
||
|
//若该商品在秒杀中,则,重新赋值
|
||
|
if len(secgoods) > 0 {
|
||
|
//秒杀价格
|
||
|
var mp = make(map[uint]flashsale.RecookSecKillGoodsModel)
|
||
|
var sl []flashsale.RecookSecKillGoodsModel
|
||
|
mysql2.Db.Table((&flashsale.RecookSecKillGoodsModel{}).TableName()).Where("sec_kill_activity_id=?", seckill.Id).Where("goods_id=?", summary.ID).Find(&sl)
|
||
|
for _, v := range sl {
|
||
|
mp[v.GoodsSkuId] = v
|
||
|
}
|
||
|
for i, sku := range summary.Sku {
|
||
|
if _, ok := mp[sku.ID]; ok {
|
||
|
summary.Sku[i].DiscountPrice = mp[sku.ID].SecKillDiscountPrice
|
||
|
summary.Sku[i].Commission = mp[sku.ID].SecKillDiscountPrice.Mul(mp[sku.ID].SecKillCommissionRate).Truncate(2)
|
||
|
} else {
|
||
|
summary.Sku[i] = goods.Sku{}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
summary.SecKill.SecKill = 1
|
||
|
summary.SecKill.SecKillEndTime = secgoods[0].ShowTimeEnd.Format("15:04:05")
|
||
|
var newsku []goods.Sku
|
||
|
minPrice := summary.Sku[0].DiscountPrice
|
||
|
maxCom := summary.Sku[0].Commission
|
||
|
for _, v := range summary.Sku {
|
||
|
if v.ID > 0 {
|
||
|
newsku = append(newsku, v)
|
||
|
if v.DiscountPrice.LessThan(minPrice) {
|
||
|
minPrice = v.DiscountPrice
|
||
|
}
|
||
|
if v.Commission.GreaterThan(maxCom) {
|
||
|
maxCom = v.Commission
|
||
|
}
|
||
|
} else {
|
||
|
continue
|
||
|
}
|
||
|
}
|
||
|
summary.SecKill.SecKillCommission = maxCom
|
||
|
summary.SecKill.SecKillMinPrice = minPrice
|
||
|
summary.Sku = newsku
|
||
|
for i, v := range summary.Attributes {
|
||
|
for i2, j := range v.Children {
|
||
|
if _, ok := mp[j.ID]; ok {
|
||
|
} else {
|
||
|
summary.Attributes[i].Children[i2] = goods.Attribute{}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
var newat []attributeSub
|
||
|
for _, v := range summary.Attributes {
|
||
|
var newattri []goods.Attribute
|
||
|
for _, j := range v.Children {
|
||
|
if j.ID > 0 {
|
||
|
newattri = append(newattri, j)
|
||
|
} else {
|
||
|
continue
|
||
|
}
|
||
|
}
|
||
|
newat = append(newat, attributeSub{
|
||
|
Name: v.Name,
|
||
|
Children: newattri,
|
||
|
})
|
||
|
}
|
||
|
summary.Attributes = newat
|
||
|
//判断结束
|
||
|
}
|
||
|
|
||
|
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,
|
||
|
})
|
||
|
|
||
|
}
|