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.
432 lines
15 KiB
432 lines
15 KiB
package goods
|
|
|
|
import (
|
|
"fmt"
|
|
"recook/internal/back"
|
|
"recook/internal/dbc"
|
|
"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"`
|
|
SalePrice decimal.Decimal `json:"sale_price"`
|
|
Min uint `json:"min"`
|
|
Limit uint `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"`
|
|
SalesVolumeInc uint `gorm:"column:sales_volume_inc" json:"sales_volume_inc"`
|
|
SaleVolume2 uint `gorm:"column:sale_volume2" json:"salesVolume2"`
|
|
SaleVolumeInc2 uint `gorm:"column:sale_volume_inc2" json:"sales_volume_inc2"`
|
|
}
|
|
|
|
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 goods.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"`
|
|
Content string `json:"content"`
|
|
}
|
|
|
|
func QueryGoodsPhotosDetail(c *gin.Context) {
|
|
var p detailParam
|
|
err := tools.ParseParams(&p, c)
|
|
if err != nil {
|
|
back.Fail(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 list []goods.DetailPhoto
|
|
dbc.DB.Order("order_no asc").Find(&list, "goods_id = ?", p.GoodsID)
|
|
var content goods.Content
|
|
dbc.DB.First(&content, "goods_id= ?", info.GoodsID)
|
|
var gd = DetailImg{
|
|
List: list,
|
|
Brand: brand,
|
|
Content: content.Content,
|
|
}
|
|
|
|
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)
|
|
|
|
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_volume2) AS sale_volume2, SUM(sale_volume_inc2) AS sale_volume_inc2, SUM(sales_volume_inc) AS sales_volume_inc,SUM(sale_inventory) AS sale_inventory").
|
|
First(&sv, "goods_id = ?", p.GoodsID)
|
|
summary.SalesVolume = sv.SalesVolume + sv.SalesVolumeInc
|
|
if p.IsSale {
|
|
summary.SalesVolume = sv.SaleVolume2 + sv.SaleVolumeInc2
|
|
}
|
|
summary.Inventory = sv.Inventory
|
|
summary.SaleInventory = sv.SaleInventory
|
|
|
|
var minAllPrice goods.AllPrice
|
|
selectMinPriceStr := "MIN(original_price) AS original_price, " +
|
|
"MIN(discount_price) AS discount_price, " +
|
|
"MIN(ROUND(discount_price-IF(extra_price=0,purchase_price*1.03,purchase_price+ extra_price), 2)) AS commission, " +
|
|
"MIN(purchase_price) AS purchase_price, " +
|
|
"MIN(min_num) AS min_num, " +
|
|
"MIN(limit_num) AS limit_num, " +
|
|
"MIN(sale_purchase_price) as sale_purchase_price, " +
|
|
"MIN(sale_extra_price) as sale_extra_price, " +
|
|
"MIN(extra_price) as extra_price"
|
|
dbc.DB.Table((&goods.Sku{}).TableName()).Select(selectMinPriceStr).First(&minAllPrice, "goods_id = ?", p.GoodsID)
|
|
minAllPrice.SalePrice = minAllPrice.GetSalePrice(u1.Level)
|
|
|
|
var maxAllPrice goods.AllPrice
|
|
selectMaxPriceStr := "MAX(original_price) AS original_price, " +
|
|
"MAX(discount_price) AS discount_price, " +
|
|
"MAX(ROUND(discount_price-IF(extra_price=0,purchase_price*1.03,purchase_price+ extra_price), 2)) AS commission, " +
|
|
"MAX(purchase_price) AS purchase_price, " +
|
|
"MAX(min_num) AS min_num, " +
|
|
"MAX(limit_num) AS limit_num, " +
|
|
"MAX(sale_purchase_price) as sale_purchase_price, " +
|
|
"MIN(sale_extra_price) as sale_extra_price, " +
|
|
"MIN(extra_price) as extra_price"
|
|
dbc.DB.Table((&goods.Sku{}).TableName()).Select(selectMaxPriceStr).First(&maxAllPrice, "goods_id = ?", p.GoodsID)
|
|
maxAllPrice.SalePrice = maxAllPrice.GetSalePrice(u1.Level)
|
|
|
|
minCommission := minAllPrice.GetSelfProfit(u1.Level)
|
|
maxCommission := maxAllPrice.GetSelfProfit(u1.Level)
|
|
|
|
summary.Price = priceBorderSub{
|
|
priceSub{
|
|
OriginalPrice: minAllPrice.OriginalPrice,
|
|
DiscountPrice: minAllPrice.DiscountPrice,
|
|
Commission: minCommission,
|
|
SalePrice: minAllPrice.SalePrice,
|
|
Min: minAllPrice.Min,
|
|
Limit: minAllPrice.Limit,
|
|
},
|
|
priceSub{
|
|
OriginalPrice: maxAllPrice.OriginalPrice,
|
|
DiscountPrice: maxAllPrice.DiscountPrice,
|
|
Commission: maxCommission,
|
|
SalePrice: maxAllPrice.SalePrice,
|
|
Min: maxAllPrice.Min,
|
|
Limit: minAllPrice.Limit,
|
|
},
|
|
}
|
|
|
|
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 {
|
|
summary.Sku[index].Commission = v.GetSelfProfit(u1.Level)
|
|
summary.Sku[index].SalePrice = v.GetSalePrice(u1.Level)
|
|
}
|
|
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
|
|
|
|
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)
|
|
}
|
|
|
|
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("count(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 imgList []string
|
|
dbc.DB.Table((&goods2.RecookGoodsNoticeImageModel{}).TableName()).Where("noticeId=?", noticeInfo.Id).Pluck("image", &imgList)
|
|
if noticeInfo.Id > 0 && now > noticeInfo.StartTime.Time.Unix() && now < noticeInfo.EndTime.Time.Unix() {
|
|
summary.Notice.Title = noticeInfo.Title
|
|
summary.Notice.Img = imgList
|
|
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,
|
|
})
|
|
|
|
}
|