package goods
import (
"fmt"
"recook/internal/back"
"recook/internal/dbc"
"recook/internal/define"
"recook/internal/model/goods"
"recook/internal/v2/lib/es"
ac2 "recook/internal/v2/model/jyy"
"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"
"strings"
mysql2 "git.oa00.com/go/mysql"
"github.com/gin-gonic/gin"
"github.com/golangkit/formatime"
"github.com/shopspring/decimal"
gorm2 "gorm.io/gorm"
"gorm.io/gorm/clause"
)
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" `
ActivityID uint ` json:"activity_id" ` // 批发活动商品
IsSale bool ` json:"is_sale" `
}
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" `
SalePrice decimal . Decimal ` json:"sale_price" `
}
// 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 && p . ActivityID == 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
status := 1
if p . IsSale {
status = 0
}
q3 := mysql2 . Db . Table ( "recook_goods_info as a" ) .
Order ( "id desc" ) . Where ( goods . Information {
BrandID : p . BrandID ,
SecondCategoryID : p . SecondCategoryID ,
PublishStatus : uint ( status ) ,
} )
if p . ActivityID != 0 {
// 批发活动id
sub := mysql2 . Db . Table ( ( & ac2 . ActivityGoods { } ) . TableName ( ) ) . Select ( "goods_id" ) . Where ( "activity_id = ?" , p . ActivityID )
q3 = q3 . Where ( "id in (?) and sale_publish = 1 and is_sale = 1" , sub )
}
findByKeyWord ( q3 , p . Keyword , & goodsList , p . Page , p . IsSale , false )
back . Suc ( c , "" , GetGoodsRespByInfoList ( goodsList , p . UserId , p . IsSale ) )
}
func findByKeyWord ( q * gorm2 . DB , str string , data * [ ] goods . Information , page uint , isSale bool , isCondition bool ) {
if str != "" {
if ! isSale {
gl , _ , _ := search_ali . SearchByAliES ( str , 20 , int ( page ) )
q = q . Where ( "a.id in (?)" , gl )
if ! isCondition {
q = q . Clauses ( clause . OrderBy {
Expression : clause . Expr { SQL : "FIELD(id,?)" , Vars : [ ] interface { } { gl } , WithoutParentheses : true } } )
}
q . Find ( & data )
} else {
like := fmt . Sprintf ( "%%%v%%" , str )
q . Where ( "is_sale = 1 and sale_publish = 1" ) . Where ( "goods_name like ?" , like ) . Limit ( 20 ) . Offset ( int ( page * 20 ) ) . 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 && p . ActivityID == 0 {
back . Fail ( c , "参数不全" )
return
}
status := 1
if p . IsSale {
status = 0
}
var goodsList [ ] goods . Information
order := fmt . Sprintf ( "vol %s, id desc" , p . Order )
q3 := mysql2 . Db . Select ( "a.*, b.vol" ) . Table ( "recook_goods_info as a" ) . Joins ( "JOIN (SELECT goods_id, sum(sales_volume + sales_volume_inc ) as vol FROM recook_goods_sku GROUP BY goods_id) as b on a.id = b.goods_id " ) . Order ( order ) . Where ( goods . Information {
BrandID : p . BrandID ,
SecondCategoryID : p . SecondCategoryID ,
PublishStatus : uint ( status ) ,
Country : p . CountryId ,
} )
if p . ActivityID != 0 {
// 批发活动id
sub := mysql2 . Db . Table ( ( & ac2 . ActivityGoods { } ) . TableName ( ) ) . Select ( "goods_id" ) . Where ( "activity_id = ?" , p . ActivityID )
q3 = q3 . Where ( "id in (?) and sale_publish = 1 and is_sale = 1" , sub )
}
findByKeyWord ( q3 , p . Keyword , & goodsList , p . Page , p . IsSale , true )
back . Suc ( c , "" , GetGoodsRespByInfoList ( goodsList , p . UserId , p . IsSale ) )
}
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 && p . ActivityID == 0 {
back . Fail ( c , "参数不全" )
return
}
var goodsIdList [ ] uint
status := 1
if p . IsSale {
status = 0
}
var goodsInfoIdList [ ] goods . Information
q3 := mysql2 . Db . Table ( "recook_goods_info as a" ) . Where ( goods . Information {
BrandID : p . BrandID ,
SecondCategoryID : p . SecondCategoryID ,
PublishStatus : uint ( status ) ,
Country : p . CountryId ,
} )
if p . ActivityID != 0 {
// 批发活动id
sub := mysql2 . Db . Table ( ( & ac2 . ActivityGoods { } ) . TableName ( ) ) . Select ( "goods_id" ) . Where ( "activity_id = ?" , p . ActivityID )
q3 = q3 . Where ( "id in (?) and sale_publish = 1 and is_sale= 1" , sub )
}
findByKeyWord ( q3 , p . Keyword , & goodsInfoIdList , p . Page , p . IsSale , true )
for _ , v := range goodsInfoIdList {
goodsIdList = append ( goodsIdList , v . ID )
}
var skuList [ ] goods . Sku
order := fmt . Sprintf ( "discount_price %s" , p . Order )
if p . IsSale {
order = fmt . Sprintf ( "sale_purchase_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, " +
"MIN(sale_purchase_price) as sale_purchase_price, " +
"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 , isSale bool ) [ ] QueryCategoryGoodsListResp {
ids := make ( [ ] uint , 0 )
bids := make ( [ ] uint , 0 )
for _ , v := range goodsList {
ids = append ( ids , v . ID )
bids = append ( bids , v . BrandID )
}
list := make ( [ ] QueryCategoryGoodsListResp , 0 )
var u user . RecookUserInfoModel
mysql2 . Db . First ( & u , "id = ?" , userID )
var sku [ ] goods . Sku
mysql2 . Db . Select (
"MIN(name), " +
"goods_id, " +
"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," +
"MIN(sale_purchase_price) AS sale_purchase_price" ) .
Group ( "goods_id" ) .
Where ( "goods_id in (?)" , ids ) .
Find ( & sku )
skuMap := make ( map [ uint ] goods . Sku )
for _ , v := range sku {
skuMap [ v . GoodsID ] = v
}
var mainPhotoList [ ] goods . MainPhoto
mysql2 . Db . Find ( & mainPhotoList , "goods_id in (?) AND is_master = 1" , ids )
mpMap := make ( map [ uint ] goods . MainPhoto )
for _ , v := range mainPhotoList {
mpMap [ v . GoodsID ] = v
}
var brandList [ ] goods . Brand
mysql2 . Db . Find ( & brandList , "id in (?)" , bids )
brandMap := make ( map [ uint ] goods . Brand )
for _ , v := range brandList {
brandMap [ v . ID ] = v
}
//国家图标放入map结束
for _ , v := range goodsList {
if isSale && v . SalePublish != 1 {
continue
}
if ! isSale && v . PublishStatus == 0 {
continue
}
ss := skuMap [ v . ID ]
mp := mpMap [ v . ID ]
brand := brandMap [ v . BrandID ]
var startTime = formatime . Second { }
var endTime = formatime . Second { }
inventory := ss . Inventory
salesVolume := ss . SalesVolume + ss . SalesVolumeInc
commission := ss . Commission
tags := make ( [ ] string , 0 )
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 := ss . 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 )
if u . Level == 10 {
commission = ss . DiscountPrice . Sub ( ss . PurchasePrice . Mul ( decimal . NewFromFloat ( 1.03 ) ) ) . Mul ( decimal . NewFromFloat ( define . Coefficient ) )
}
recookGoodsInfoModel := & goods2 . RecookGoodsInfoModel { }
space := " "
list = append ( list , QueryCategoryGoodsListResp {
ID : v . ID ,
GoodsName : strings . Join ( [ ] string { v . GoodsName , strings . Replace ( ss . Name , "+" , space , - 1 ) } , space ) ,
BrandName : brand . Name + "品牌馆" ,
BrandImg : brand . LogoURL ,
BrandId : brand . ID ,
Description : v . Description ,
Inventory : inventory ,
SalesVolume : salesVolume ,
MainPhotoURL : mp . URL ,
PromotionName : "" ,
OriginalPrice : ss . OriginalPrice ,
DiscountPrice : ss . DiscountPrice ,
Commission : commission ,
Tags : tags ,
Percent : 0 , //百分比,-1不显示
StartTime : startTime ,
EndTime : endTime ,
Coupon : ss . Coupon ,
IsImport : v . IsImport ,
Storehouse : v . Storehouse ,
IsFerme : v . IsFerme ,
HasCoin : recookGoodsInfoModel . HasCoin ( v . Storehouse ) ,
HasBalance : recookGoodsInfoModel . HasBalance ( v . Storehouse ) ,
GysId : v . VendorID ,
CountryIcon : "" ,
SalePrice : ss . GetSalePrice ( u . Level ) ,
} )
}
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 )
if u . Level == 10 {
commission = v . DiscountPrice . Sub ( v . PurchasePrice . Mul ( decimal . NewFromFloat ( 1.03 ) ) ) . Mul ( decimal . NewFromFloat ( define . Coefficient ) ) . Round ( 2 )
}
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 : "" ,
SalePrice : v . GetSalePrice ( u . Level ) ,
} )
}
return list
}
func GetListByLive ( goodsList [ ] goods . Information , userID uint , isSale bool ) [ ] QueryCategoryGoodsListResp {
return GetGoodsRespByInfoList ( goodsList , userID , isSale )
}
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 )
}