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

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,
})
}