package goods
import (
"fmt"
"recook/internal/back"
"recook/internal/cache"
"recook/internal/dbc"
"recook/internal/model/goods"
"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, " +
"SUM(sales_volume_inc) AS sales_volume_inc, " +
"MIN(original_price) AS original_price, " +
"MIN(discount_price) AS discount_price, " +
"MIN(purchase_price) AS purchase_price, " +
"MIN(commission) AS commission, " +
"goods_id" ) . Order ( order ) . Group ( "goods_id" ) .
Find ( & skuList , "goods_id IN (?)" , goodsIdList )
back . Suc ( c , "" , GetGoodsRespBySkuList ( skuList , p . UserId ) )
}
// 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 {
if v . PublishStatus == 0 {
continue
}
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, " +
"SUM(sales_volume_inc) AS sales_volume_inc, " +
"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 := sku . SalesVolume + sku . SalesVolumeInc
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 . Zero
rate2 := decimal . Zero
rate3 := decimal . Zero
if u . Level == 1 {
rate1 = decimal . NewFromFloat32 ( 0.4 )
rate2 = decimal . NewFromFloat32 ( 0.1 )
}
if u . Level == 2 {
rate1 = decimal . NewFromFloat32 ( 0.4 )
rate2 = decimal . NewFromFloat32 ( 0.1 )
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 , uid uint ) [ ] QueryCategoryGoodsListResp {
list := make ( [ ] QueryCategoryGoodsListResp , 0 , 0 )
var u user . RecookUserInfoModel
mysql2 . Db . First ( & u , "id = ?" , uid )
rate1 := decimal . Zero
rate2 := decimal . Zero
rate3 := decimal . Zero
if u . Level == 1 {
rate1 = decimal . NewFromFloat32 ( 0.4 )
rate2 = decimal . NewFromFloat32 ( 0.1 )
}
if u . Level == 2 {
rate1 = decimal . NewFromFloat32 ( 0.4 )
rate2 = decimal . NewFromFloat32 ( 0.1 )
rate3 = decimal . NewFromFloat32 ( 0.2 )
}
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 )
if goodsInfo . PublishStatus == 0 {
continue
}
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 := v . SalesVolume + v . SalesVolumeInc
discountPrice := v . DiscountPrice
commission := v . Commission
inventory = v . Inventory //sku库存
base := v . GetBase ( )
commission1 := base . Mul ( rate1 ) . Round ( 2 )
commission2 := base . Mul ( rate2 ) . Round ( 2 )
commission3 := base . Mul ( rate3 ) . Round ( 2 )
fmt . Println ( commission1 , commission2 , commission3 , base , v . PurchasePrice , v . DiscountPrice )
commission = commission1 . Add ( commission2 ) . Add ( commission3 )
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 : "" ,
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 , userID uint ) [ ] QueryCategoryGoodsListResp {
return GetGoodsRespByInfoList ( goodsList , userID )
}
func secKillAbout ( list [ ] QueryCategoryGoodsListResp ) ( result [ ] QueryCategoryGoodsListResp ) {
//新增秒杀的图标
//获取当前时间段的秒杀商品
now := time . Now ( )
var seckill flashsale . RecookSecKillModel
dbc . DB . Table ( seckill . TableName ( ) ) . Where ( "activity_start_time<?" , now ) . Where ( "activity_end_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 ( "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 sgal [ ] int64
q := dbc . DB . Table ( ( & flashsale . RecookSecKillSortModel { } ) . TableName ( ) ) . Where ( "show_time_start<?" , now2 ) . Where ( "show_time_end>?" , 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 ( "activity_end_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 ( "show_time_end>?" , 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 )
}