package jyy
import (
"errors"
"fmt"
"recook/internal/dbc"
"recook/internal/libs/bean"
"recook/internal/model/order"
"recook/internal/model/order_preview"
user2 "recook/internal/model/user"
"recook/internal/v2/model/company"
"recook/internal/v2/model/jyy"
goods2 "recook/internal/v2/model/recook/goods"
manage "recook/internal/v2/model/recook/order"
"recook/internal/v2/model/recook/user"
"time"
"github.com/golangkit/formatime"
"github.com/shopspring/decimal"
"gorm.io/gorm"
"git.oa00.com/go/mysql"
)
type logic struct {
}
var Logic = logic { }
func ( o logic ) Banners ( ) ( res [ ] jyy . Banner , err error ) {
now := time . Now ( )
mysql . Db . Where ( "start < ?" , now ) . Where ( "end > ?" , now ) . Order ( "order_sort asc" ) . Order ( "id desc" ) . Find ( & res )
return
}
func ( o logic ) Activities ( ) ( res [ ] jyy . Activity , err error ) {
mysql . Db . Where ( "status = 1" ) . Order ( "order_sort asc" ) . Order ( "id desc" ) . Find ( & res )
return
}
type ArgsEntryReq struct {
UserID uint ` json:"user_id" `
}
type ShopCartSku struct {
ID uint ` json:"id" `
SkuID uint ` json:"sku_id" `
DiscountPrice decimal . Decimal ` json:"discount_price" `
SalePrice decimal . Decimal ` json:"sale_price" `
Quantity uint ` json:"quantity" `
Limit int ` json:"limit" `
Min int ` json:"min" `
SkuName string ` json:"sku_name" `
GoodsName string ` json:"goods_name,omitempty" `
SalePublish uint ` json:"sale_publish" `
PicUrl string ` json:"pic_url" `
GoodsID uint ` json:"goods_id" `
}
type ShopCartEntry struct {
GoodsID uint ` json:"goods_id" `
GoodsName string ` json:"goods_name" `
MainPhoto string ` json:"main_photo" `
SkuList [ ] ShopCartSku ` json:"sku_list" `
SalePublish uint ` json:"sale_publish" `
}
func ( o logic ) ShopCartEntries ( args ArgsEntryReq ) ( res [ ] ShopCartSku ) {
sc := make ( [ ] jyy . ShopCartEntry , 0 )
mysql . Db . Model ( & jyy . ShopCartEntry { } ) . Where ( "user_id = ?" , args . UserID ) . Find ( & sc )
ids := make ( [ ] uint , 0 )
idsMap := make ( map [ uint ] uint )
skuMap := make ( map [ uint ] uint )
for _ , v := range sc {
ids = append ( ids , v . SkuID )
idsMap [ v . SkuID ] = v . Quantity
skuMap [ v . SkuID ] = v . ID
}
var u1 user . RecookUserInfoModel
mysql . Db . First ( & u1 , "id = ?" , args . UserID )
skuList := make ( [ ] goods2 . RecookGoodsSkuModel , 0 )
mysql . Db . Preload ( "GoodsInfo" ) . Where ( "id in (?)" , ids ) . Find ( & skuList )
for _ , v := range skuList {
res = append ( res , ShopCartSku {
ID : skuMap [ v . Id ] ,
SkuID : v . Id ,
DiscountPrice : v . DiscountPrice ,
SalePrice : v . GetSalePrice ( u1 . Level ) ,
Quantity : idsMap [ v . Id ] ,
Limit : v . Limit ,
Min : v . Min ,
SkuName : v . Name ,
PicUrl : v . PicURL ,
SalePublish : v . GoodsInfo . SalePublish ,
GoodsName : v . GoodsInfo . GoodsName ,
GoodsID : v . GoodsId ,
} )
}
// goodsMap := make(map[uint][]ShopCartSku)
// for _, v := range skuList {
// goodsMap[v.GoodsId] = append(goodsMap[v.GoodsId], ShopCartSku{
// ID: skuMap[v.Id],
// SkuID: v.Id,
// DiscountPrice: v.DiscountPrice,
// SalePrice: v.GetSalePrice(u1.Level),
// Quantity: idsMap[v.Id],
// Limit: v.Limit,
// Min: v.Min,
// SkuName: v.Name,
// })
// }
// inRes := make(map[uint]bool)
// for _, v := range skuList {
// if inRes[v.GoodsId] {
// continue
// }
// inRes[v.GoodsId] = true
// res = append(res, ShopCartEntry{
// GoodsID: v.GoodsId,
// GoodsName: v.GoodsInfo.GoodsName,
// MainPhoto: v.GoodsInfo.MainPhoto.Url,
// SkuList: goodsMap[v.GoodsId],
// SalePublish: v.GoodsInfo.SalePublish,
// })
// }
return
}
type skuEntry struct {
SkuID uint ` json:"sku_id" `
Quantity int ` json:"quantity" `
}
type ArgsAddSku struct {
UserID uint ` json:"user_id" `
IsUpdate bool
SkuList [ ] skuEntry ` json:"sku_list" validate:"required,gte=1" `
}
func ( o logic ) ShopCartAddSku ( args ArgsAddSku ) ( err error ) {
var skuList [ ] goods2 . RecookGoodsSkuModel
ids := make ( [ ] uint , 0 )
idMap := make ( map [ uint ] int )
for _ , v := range args . SkuList {
ids = append ( ids , v . SkuID )
idMap [ v . SkuID ] = v . Quantity
}
mysql . Db . Preload ( "GoodsInfo" ) . Find ( & skuList , "id in (?)" , ids )
if len ( skuList ) != len ( ids ) {
return errors . New ( "商品选择错误" )
}
for _ , v := range skuList {
if v . GoodsInfo . SalePublish != 1 {
return fmt . Errorf ( "%d商品下架" , v . GoodsId )
}
if ! v . GoodsInfo . IsSale {
return fmt . Errorf ( "%d商品不可批发" , v . GoodsId )
}
if idMap [ v . Id ] < v . Min {
return fmt . Errorf ( "%s商品最低%d" , v . Name , v . Min )
}
if idMap [ v . Id ] % v . Min != 0 {
return fmt . Errorf ( "%s商品每手至少%d" , v . Name , v . Min )
}
}
data := make ( [ ] jyy . ShopCartEntry , 0 )
mysql . Db . Find ( & data , "user_id = ?" , args . UserID )
isUsed := make ( map [ uint ] bool )
for _ , v := range data {
if idMap [ v . SkuID ] != 0 {
if args . IsUpdate {
v . Quantity = uint ( idMap [ v . SkuID ] )
} else {
v . Quantity += uint ( idMap [ v . SkuID ] )
}
mysql . Db . Save ( v )
isUsed [ v . SkuID ] = true
}
}
res := make ( [ ] jyy . ShopCartEntry , 0 )
for _ , v := range skuList {
if isUsed [ v . Id ] {
continue
}
res = append ( res , jyy . ShopCartEntry {
SkuID : v . Id ,
GoodsID : v . GoodsId ,
UserID : args . UserID ,
Quantity : uint ( idMap [ v . Id ] ) ,
} )
}
if len ( res ) == 0 {
return nil
}
if err = mysql . Db . Create ( & res ) . Error ; err != nil {
return err
}
return
}
func ( o logic ) ShopCartDeleteSku ( args ArgsAddSku ) ( err error ) {
ids := make ( [ ] uint , 0 )
for _ , v := range args . SkuList {
ids = append ( ids , v . SkuID )
}
err = mysql . Db . Delete ( & jyy . ShopCartEntry { } , "sku_id in (?)" , ids ) . Error
return
}
type OrderPreview struct {
UserID uint ` json:"user_id" validate:"required" `
SkuList [ ] skuEntry ` json:"sku_list" validate:"required" `
Channel uint ` json:"channel" validate:"oneof=0 1" `
}
type OrderPreviewInfo struct {
PreviewID uint ` json:"preview_id" `
Addr user2 . Addr ` json:"Addr" `
SkuList [ ] ShopCartSku ` json:"sku_list" `
Total decimal . Decimal ` json:"total" `
}
func ( o logic ) OrderPreview ( args OrderPreview ) ( err error , res OrderPreviewInfo ) {
var u1 user . RecookUserInfoModel
if err = mysql . Db . First ( & u1 , "id = ?" , args . UserID ) . Error ; err != nil {
return
}
if u1 . Level < 2 || ( u1 . Level == 2 && ! u1 . IsOffline ) {
err = errors . New ( "您目前还不是VIP店铺, 无法进行批发操作" )
return
}
var skuList [ ] goods2 . RecookGoodsSkuModel
ids := make ( [ ] uint , 0 )
idMap := make ( map [ uint ] int )
for _ , v := range args . SkuList {
ids = append ( ids , v . SkuID )
idMap [ v . SkuID ] = v . Quantity
}
mysql . Db . Preload ( "GoodsInfo.MainPhoto" ) .
Preload ( "GoodsInfo.Brand" ) .
Preload ( "GoodsInfo.FirstCategory" ) .
Preload ( "GoodsInfo.SecondCategory" ) .
Find ( & skuList , "id in (?)" , ids )
if len ( skuList ) != len ( ids ) {
err = errors . New ( "商品选择错误" )
return
}
for _ , v := range skuList {
if v . GoodsInfo . SalePublish != 1 {
err = fmt . Errorf ( "%d商品下架" , v . GoodsId )
return
}
if ! v . GoodsInfo . IsSale {
err = fmt . Errorf ( "%d商品不可批发" , v . GoodsId )
return
}
if idMap [ v . Id ] < v . Min {
err = fmt . Errorf ( "%s商品最低%d" , v . Name , v . Min )
return
}
if idMap [ v . Id ] % v . Min != 0 {
err = fmt . Errorf ( "%s商品每手至少%d" , v . Name , v . Min )
return
}
}
goodsTotalAmount := decimal . Zero
cost := decimal . Zero
preOrderGoodsList := make ( [ ] order_preview . GoodsDetail , 0 , 0 )
sl := make ( [ ] ShopCartSku , 0 )
for _ , v := range skuList {
if v . SalePurchasePrice . IsZero ( ) {
err = errors . New ( "价格异常" )
return
}
qu := decimal . NewFromInt ( int64 ( idMap [ v . Id ] ) )
goodsInfo := v . GoodsInfo
one := order_preview . GoodsDetail {
VendorID : goodsInfo . VendorID ,
VendorName : "" ,
BrandID : goodsInfo . BrandID ,
BrandName : goodsInfo . Brand . Name ,
CategoryName : goodsInfo . FirstCategory . Name + "/" + goodsInfo . SecondCategory . Name ,
GoodsID : goodsInfo . Id ,
GoodsName : goodsInfo . GoodsName ,
IsJoinTeamPerformance : goodsInfo . IsJoinTeamPerformance ,
Hash : goodsInfo . Hash ,
SkuID : v . Id ,
SkuName : v . Name ,
SkuCode : v . Code ,
MainPhotoURL : goodsInfo . MainPhoto . Url ,
Quantity : uint ( idMap [ v . Id ] ) ,
FreightID : goodsInfo . FreightID ,
Weight : goodsInfo . Weight ,
PromotionSkuId : 0 ,
PromotionGoodsId : 0 ,
PromotionName : "" ,
UnitPrice : v . GetSalePrice ( u1 . Level ) ,
PurchasePrice : v . SalePurchasePrice ,
TotalCommission : decimal . Zero ,
GoodsAmount : v . GetSalePrice ( u1 . Level ) . Mul ( qu ) ,
IsImport : goodsInfo . IsImport ,
Storehouse : goodsInfo . Storehouse ,
IsFerme : goodsInfo . IsFerme ,
ActualAmount : v . GetSalePrice ( u1 . Level ) . Mul ( qu ) ,
}
sl = append ( sl , ShopCartSku {
SkuID : v . Id ,
DiscountPrice : v . DiscountPrice ,
SalePrice : v . GetSalePrice ( u1 . Level ) ,
Quantity : uint ( idMap [ v . Id ] ) ,
Limit : v . Limit ,
Min : v . Min ,
SkuName : v . Name ,
GoodsName : v . GoodsInfo . GoodsName ,
PicUrl : v . PicURL ,
} )
preOrderGoodsList = append ( preOrderGoodsList , one )
goodsTotalAmount = goodsTotalAmount . Add ( v . GetSalePrice ( u1 . Level ) . Mul ( qu ) )
cost = cost . Add ( v . PurchasePrice . Mul ( qu ) )
}
if goodsTotalAmount . LessThanOrEqual ( decimal . Zero ) {
err = fmt . Errorf ( "订单价格异常" )
return
}
var defaultAddr user2 . Addr
{
err = mysql . Db . First ( & defaultAddr , "user_id = ? AND is_default = 1" , args . UserID ) . Error
if err != nil && err != gorm . ErrRecordNotFound {
return
}
}
if err = mysql . Db . Transaction ( func ( tx * gorm . DB ) error {
preOrderInfo := order_preview . Information {
AncestorID : 0 ,
ParentID : 0 ,
UserID : args . UserID ,
SharerID : 0 ,
Title : skuList [ 0 ] . GoodsInfo . GoodsName + "等多件" ,
BrandCouponTotalAmount : decimal . Zero ,
UniverseCouponTotalAmount : decimal . Zero ,
CoinTotalAmount : decimal . Zero ,
ExpressTotalFee : decimal . Zero ,
GoodsTotalAmount : goodsTotalAmount ,
GoodsTotalCommission : decimal . Zero ,
ActualTotalAmount : goodsTotalAmount ,
Channel : args . Channel ,
Cost : cost ,
CreatedAt : formatime . NewSecondNow ( ) ,
OrderType : 2 ,
}
if e := tx . Create ( & preOrderInfo ) . Error ; e != nil {
return e
}
for i := range preOrderGoodsList {
preOrderGoodsList [ i ] . OrderID = preOrderInfo . ID
}
if e := tx . Create ( & preOrderGoodsList ) . Error ; e != nil {
return e
}
preOrderAddr := order_preview . Addr {
OrderID : preOrderInfo . ID ,
AddressID : defaultAddr . ID ,
Province : defaultAddr . Province ,
City : defaultAddr . City ,
District : defaultAddr . District ,
Address : defaultAddr . Address ,
ReceiverName : defaultAddr . Name ,
Mobile : defaultAddr . Mobile ,
IsDeliveryArea : 1 ,
}
if e := tx . Create ( & preOrderAddr ) . Error ; e != nil {
return e
}
res . PreviewID = preOrderInfo . ID
res . Addr = defaultAddr
res . SkuList = sl
res . Total = goodsTotalAmount
return nil
} ) ; err != nil {
return
}
return
}
type OrderAddrUpdate struct {
PreviewID uint ` json:"preview_id" `
AddressID uint ` json:"address_id" `
BuyerMessage string ` json:"buyer_message" `
}
func ( o logic ) OrderUpdate ( args OrderAddrUpdate ) ( err error ) {
var addr user2 . Addr
err = mysql . Db . First ( & addr , "id = ?" , args . AddressID ) . Error
if err != nil {
return
}
var previewOrderAddr order_preview . Addr
err = mysql . Db . First ( & previewOrderAddr , "order_id = ?" , args . PreviewID ) . Error
if err != nil {
return
}
if err = mysql . Db . Transaction ( func ( tx * gorm . DB ) error {
if addr . ID > 0 {
if e := tx . Model ( & previewOrderAddr ) . Updates ( map [ string ] interface { } {
"address_id" : addr . ID ,
"province" : addr . Province ,
"city" : addr . City ,
"district" : addr . District ,
"address" : addr . Address ,
"receiver_name" : addr . Name ,
"mobile" : addr . Mobile ,
"is_delivery_area" : 1 ,
} ) . Error ; e != nil {
return e
}
}
if e := tx . Table ( ( & order_preview . Information { } ) . TableName ( ) ) .
Where ( "id = ?" , args . PreviewID ) .
Updates ( map [ string ] interface { } { "buyer_message" : args . BuyerMessage } ) . Error ; e != nil {
return e
}
return nil
} ) ; err != nil {
return
}
return
}
func ( o logic ) Contact ( ) ( res jyy . Contact ) {
mysql . Db . First ( & res )
return
}
type ArgsProfitListReq struct {
UserID uint ` json:"user_id" `
Date string ` json:"date" `
ShopID uint ` json:"shop_id" `
Kind uint ` json:"kind" `
}
type ProfitSaleEntry struct {
Name string ` json:"name" `
Amount decimal . Decimal ` json:"amount" `
Income decimal . Decimal ` json:"income" `
NotIncome decimal . Decimal ` json:"not_income" `
Count int ` json:"count" `
ShopID uint ` json:"shop_id" `
}
type ProfitDetail struct {
All decimal . Decimal ` json:"all" `
WeiDaoZ decimal . Decimal ` json:"wei_dao_z" `
YiDaoZ decimal . Decimal ` json:"yi_dao_z" `
Entry [ ] ProfitSaleEntry ` json:"entry" `
}
func ( o logic ) ProfitSaleList ( args ArgsProfitListReq ) ( res ProfitDetail , err error ) {
var p [ ] order . Profit
mysql . Db . Where ( "type = 7" ) . Find ( & p , "user_id = ?" , args . UserID )
ids := make ( [ ] uint , 0 )
incomeMap := make ( map [ uint ] decimal . Decimal )
for _ , v := range p {
ids = append ( ids , v . OrderID )
incomeMap [ v . OrderID ] = incomeMap [ v . OrderID ] . Add ( v . Income )
res . All = res . All . Add ( v . Income )
}
var ods [ ] manage . RecookOrderInfoModel
mysql . Db . Preload ( "User" ) . Find ( & ods , "id in (?)" , ids )
userMap := make ( map [ uint ] [ ] manage . RecookOrderInfoModel )
for _ , v := range ods {
userMap [ v . UserId ] = append ( userMap [ v . UserId ] , v )
}
for id , v := range userMap {
amount := decimal . Zero
income := decimal . Zero
for _ , j := range v {
amount = amount . Add ( j . ActualTotalAmount )
income = income . Add ( incomeMap [ j . Id ] )
}
res . Entry = append ( res . Entry , ProfitSaleEntry {
ShopID : id ,
Name : v [ 0 ] . User . Nickname ,
Amount : amount ,
Income : income ,
Count : len ( v ) ,
} )
}
return
}
func ( o logic ) ProfitSalePerson ( args ArgsProfitListReq ) ( res ProfitDetail , err error ) {
var p [ ] order . Profit
now , e := time . ParseInLocation ( "2006" , args . Date , time . Local )
if e != nil {
err = errors . New ( "时间格式异常" + e . Error ( ) )
}
mysql . Db . Where ( "type = 7" ) . Find ( & p , "user_id = ? and created_at between ? and ?" , args . UserID , now , now . AddDate ( 1 , 0 , 0 ) )
ids := make ( [ ] uint , 0 )
incomeMap := make ( map [ uint ] decimal . Decimal )
for _ , v := range p {
ids = append ( ids , v . OrderID )
incomeMap [ v . OrderID ] = incomeMap [ v . OrderID ] . Add ( v . Income )
res . All = res . All . Add ( v . Income )
}
var ods [ ] manage . RecookOrderInfoModel
mysql . Db . Preload ( "User" ) . Find ( & ods , "id in (?) and user_id = ?" , ids , args . ShopID )
dateMap := make ( map [ string ] [ ] manage . RecookOrderInfoModel )
for _ , v := range ods {
key := v . CreatedAt . Time . Format ( "2006-01" )
dateMap [ key ] = append ( dateMap [ key ] , v )
}
for id , v := range dateMap {
amount := decimal . Zero
income := decimal . Zero
for _ , j := range v {
amount = amount . Add ( j . ActualTotalAmount )
income = income . Add ( incomeMap [ j . Id ] )
}
res . Entry = append ( res . Entry , ProfitSaleEntry {
ShopID : 0 ,
Name : id ,
Amount : amount ,
Income : income ,
Count : len ( v ) ,
} )
}
return
}
func ( o logic ) ProfitShopList ( args ArgsProfitListReq ) ( res ProfitDetail , err error ) {
var p [ ] order . Profit
query := mysql . Db . Where ( "type = ?" , args . Kind ) . Where ( "user_id = ?" , args . UserID )
{
if args . Date != "" {
now , e := time . ParseInLocation ( "200601" , args . Date , time . Local )
if e != nil {
err = errors . New ( "时间格式异常" + e . Error ( ) )
return
}
query = query . Where ( "created_at between ? and ?" , now , now . AddDate ( 0 , 1 , 0 ) )
}
}
query . Find ( & p )
ids := make ( [ ] uint , 0 )
incomeMap := make ( map [ uint ] decimal . Decimal )
NotIncomeMap := make ( map [ uint ] decimal . Decimal )
for _ , v := range p {
ids = append ( ids , v . OrderID )
res . All = res . All . Add ( v . Income )
if v . Status == 0 {
NotIncomeMap [ v . OrderID ] = incomeMap [ v . OrderID ] . Add ( v . Income )
res . WeiDaoZ = res . WeiDaoZ . Add ( v . Income )
}
if v . Status == 2 {
incomeMap [ v . OrderID ] = incomeMap [ v . OrderID ] . Add ( v . Income )
res . YiDaoZ = res . YiDaoZ . Add ( v . Income )
}
}
var ods [ ] manage . RecookOrderInfoModel
mysql . Db . Preload ( "User" ) . Find ( & ods , "id in (?)" , ids )
dateMap := make ( map [ string ] [ ] manage . RecookOrderInfoModel )
if args . Date == "" {
for _ , v := range ods {
key := v . CreatedAt . Time . Format ( "2006" )
dateMap [ key ] = append ( dateMap [ key ] , v )
}
} else {
for _ , v := range ods {
key := v . CreatedAt . Time . Format ( "01-02" )
dateMap [ key ] = append ( dateMap [ key ] , v )
}
}
for id , v := range dateMap {
income := decimal . Zero
notIncome := decimal . Zero
for _ , j := range v {
income = income . Add ( incomeMap [ j . Id ] )
notIncome = notIncome . Add ( NotIncomeMap [ j . Id ] )
}
res . Entry = append ( res . Entry , ProfitSaleEntry {
ShopID : 0 ,
Name : id ,
Amount : decimal . Zero ,
Income : income ,
NotIncome : notIncome ,
Count : len ( v ) ,
} )
}
return
}
type Profit struct {
Total decimal . Decimal ` json:"total" gorm:"total" `
Data [ ] struct {
Name string ` json:"name" gorm:"name" `
Count int ` json:"count" gorm:"count" `
Amount decimal . Decimal ` json:"amount" gorm:"amount" `
} ` json:"data" `
}
type ArgsProfitCount struct {
ArgsProfitListReq
Start string ` json:"start" `
End string ` json:"end" `
}
func ( o logic ) ProfitCount ( args ArgsProfitCount ) ( res Profit , err error ) {
query := mysql . Db . Model ( & order . Information { } ) .
Where ( "user_id = ?" , args . UserID ) .
Where ( "order_type = 2" ) .
Where ( "status in (1, 4)" )
if args . Start != "" {
query = query . Where ( "created_at > ?" , args . Start )
}
if args . End != "" {
query = query . Where ( "created_at < ?" , args . End )
}
amount := make ( [ ] decimal . Decimal , 0 )
q1 := query . Select ( "IFNULL(SUM(actual_total_amount), 0) as total" )
q1 . Pluck ( "total" , & amount )
res . Total = amount [ 0 ]
switch args . Kind {
case 1 :
// 年为单位
query = query . Select ( "YEAR(created_at) as name, count(*) as count, SUM(actual_total_amount) as amount " ) . Group ( "YEAR(created_at)" )
case 2 :
// 月为单位
query = query . Select ( "DATE_FORMAT(created_at,'%Y-%m') as name, count(*) as count, SUM(actual_total_amount) as amount " ) . Group ( "DATE_FORMAT(created_at,'%Y-%m')" )
case 3 :
// 日
query = query . Select ( "DATE_FORMAT(created_at, '%Y-%m-%d') as name, count(*) as count, SUM(actual_total_amount) as amount " ) . Group ( "DATE_FORMAT(created_at, '%Y-%m-%d')" )
}
query . Scan ( & res . Data )
return
}
func ( o logic ) CompanyInfo ( id uint ) ( res company . Info ) {
mysql . Db . First ( & res , "user_id = ?" , id )
return
}
type ApplyListReq struct {
bean . Page
ID uint ` json:"-" `
Month * time . Time ` json:"month" `
}
func ( o logic ) CompanyApplyList ( args ApplyListReq ) ( res [ ] company . Apply , total int64 ) {
query := mysql . Db . Table ( ( & company . Apply { } ) . TableName ( ) ) . Where ( "user_id = ?" , args . ID )
query . Count ( & total )
query . Order ( "id desc" ) . Limit ( args . GetLimit ( ) ) . Offset ( args . GetStart ( ) ) . Find ( & res )
return
}
func ( o logic ) CompanyApply ( args company . Apply ) error {
key := fmt . Sprintf ( "user:withdrawal:%d" , args . UserID )
lock := dbc . Rds . SetNX ( key , 1 , time . Second * 15 )
defer dbc . Rds . Del ( key )
if ! lock . Val ( ) {
return errors . New ( "请勿重复操作" )
}
var wallet user . RecookUserWalletModel
if e := mysql . Db . First ( & wallet , "user_id = ?" , args . UserID ) . Error ; e != nil {
return e
}
if args . Balance . IsZero ( ) {
return errors . New ( "没有可以提现的收益" )
}
res := o . CompanyAllAmount ( uint ( args . UserID ) )
args . Balance = res . Balance
args . Amount = res . ActualAmount
// args.Withdrawal = res.Withdrawal
args . TaxAmount = res . TaxAmount
args . ActualAmount = res . ActualAmount
var company company . Info
mysql . Db . First ( & company , "user_id = ?" , args . UserID )
args . CompanyID = int ( company . ID )
return mysql . Db . Transaction ( func ( tx * gorm . DB ) error {
if e := tx . Create ( & args ) . Error ; e != nil {
return e
}
if e := tx . Model ( & wallet ) . Update ( "balance" , gorm . Expr ( "balance - ?" , args . Balance ) ) . Error ; e != nil {
return e
}
if e := tx . Table ( ( & order . Profit { } ) . TableName ( ) ) .
Where ( "user_id = ?" , args . UserID ) .
Where ( "deal_id = 0" ) .
Update ( "deal_id" , args . ID ) . Error ; e != nil {
return e
}
return nil
} )
}
type Data struct {
Balance decimal . Decimal ` json:"balance" `
TaxAmount decimal . Decimal ` json:"tax_amount" `
Withdrawal decimal . Decimal ` json:"withdrawal" `
ActualAmount decimal . Decimal ` json:"actual_amount" `
}
func ( o logic ) CompanyAllAmount ( id uint ) ( res Data ) {
var u user2 . Information
mysql . Db . First ( & u , "id = ?" , id )
var record [ ] order . Profit
mysql . Db . Where ( "user_id = ?" , id ) . Where ( "status = 2" ) . Where ( "deal_id = 0" ) . Find ( & record )
var enterprise company . Info
mysql . Db . First ( & enterprise , "user_id = ?" , id )
if ! u . IsEnterprise {
// 普通用户
rate := decimal . NewFromFloat ( 0.13 )
cr := decimal . NewFromFloat ( 0.07 )
for _ , v := range record {
res . Balance = res . Balance . Add ( v . Income )
if v . Type == order . Card {
res . TaxAmount = res . TaxAmount . Add ( v . Income . Mul ( cr ) . Round ( 2 ) )
} else {
res . TaxAmount = res . TaxAmount . Add ( v . Income . Mul ( rate ) . Round ( 2 ) )
}
}
res . ActualAmount = res . Balance . Sub ( res . TaxAmount )
} else {
rate := decimal . NewFromFloat ( 0.13 )
if enterprise . TaxType == "一般纳税人" {
rate = decimal . NewFromFloat ( 0.07 )
}
for _ , v := range record {
res . Balance = res . Balance . Add ( v . Income )
if v . Type == order . Card && enterprise . TaxType != "一般纳税人" {
res . TaxAmount = res . TaxAmount .
Add (
v . Income .
Div ( decimal . NewFromFloat ( 1.06 ) ) .
Mul ( decimal . NewFromFloat ( 0.06 ) ) .
Mul ( decimal . NewFromFloat ( 1.12 ) ) . Round ( 2 ) )
} else {
res . TaxAmount = res . TaxAmount .
Add ( v . Income . Div ( decimal . NewFromFloat ( 1.13 ) ) . Mul ( rate ) . Mul ( decimal . NewFromFloat ( 1.12 ) ) . Round ( 2 ) )
}
}
res . ActualAmount = res . Balance . Sub ( res . TaxAmount )
}
return
}