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.
250 lines
6.4 KiB
250 lines
6.4 KiB
package service |
|
|
|
import ( |
|
"context" |
|
"fmt" |
|
"sort" |
|
"time" |
|
|
|
"go-common/app/interface/main/growup/dao" |
|
"go-common/app/interface/main/growup/model" |
|
|
|
"go-common/library/ecode" |
|
"go-common/library/log" |
|
xtime "go-common/library/time" |
|
) |
|
|
|
var ( |
|
_display = 2 |
|
_bigVipType = 1 |
|
_remark = "激励兑换" |
|
) |
|
|
|
// GoodsState get goods new state |
|
func (s *Service) GoodsState(c context.Context) (data interface{}, err error) { |
|
var newDisplay string |
|
goods, err := s.dao.GetDisplayGoods(c, _display) |
|
if err != nil { |
|
log.Error("s.dao.GetDisplayGoods error(%v)", err) |
|
return |
|
} |
|
if len(goods) > 0 { |
|
sort.Slice(goods, func(i, j int) bool { |
|
return goods[i].DisplayOnTime > goods[j].DisplayOnTime |
|
}) |
|
newDisplay = fmt.Sprintf("%s+%d+%d", goods[0].ProductID, goods[0].GoodsType, goods[0].DisplayOnTime) |
|
} |
|
data = map[string]interface{}{ |
|
"new_display": newDisplay, |
|
"open_exchange": time.Now().Day() >= 8, // 1-7号不开放兑换 |
|
} |
|
return |
|
} |
|
|
|
// GoodsShow show goods |
|
func (s *Service) GoodsShow(c context.Context, mid int64) (goods []*model.GoodsInfo, err error) { |
|
goods, err = s.dao.GetDisplayGoods(c, _display) |
|
if err != nil { |
|
log.Error("s.dao.GetDisplayGoods error(%v)", err) |
|
return |
|
} |
|
vips, err := s.dao.ListVipProducts(c, mid) |
|
if err != nil { |
|
log.Error("s.dao.ListVipProducts error(%v)", err) |
|
return |
|
} |
|
|
|
// get vip price |
|
for _, g := range goods { |
|
if g.GoodsType != _bigVipType { |
|
continue |
|
} |
|
if v, ok := vips[g.ProductID]; ok { |
|
g.Month = v.Month |
|
g.ProductName = v.ProductName |
|
g.OriginPrice = v.OriginPrice |
|
g.CurrentPrice = int64(dao.Round(dao.Mul(float64(v.OriginPrice), float64(g.Discount)/float64(100)), 0)) |
|
} |
|
} |
|
sort.Slice(goods, func(i, j int) bool { |
|
return goods[i].Month < goods[j].Month |
|
}) |
|
return |
|
} |
|
|
|
// GoodsRecord get goods record |
|
func (s *Service) GoodsRecord(c context.Context, mid int64, page, size int) (monthOrder map[string][]*model.GoodsOrder, count int, err error) { |
|
monthOrder = make(map[string][]*model.GoodsOrder) |
|
if page == 0 { |
|
page = 1 |
|
} |
|
start, end := (page-1)*size, page*size |
|
|
|
count, err = s.dao.GetGoodsOrderCount(c, mid) |
|
if err != nil { |
|
log.Error("s.dao.GetGoodsRecordCount error(%v)", err) |
|
return |
|
} |
|
|
|
orders, err := s.dao.GetGoodsOrders(c, mid, start, end) |
|
if err != nil { |
|
log.Error("s.dao.GetGoodsOrders error(%v)", err) |
|
return |
|
} |
|
for i := 0; i < len(orders); i++ { |
|
month := orders[i].OrderTime.Time().Format("2006-01") |
|
if _, ok := monthOrder[month]; !ok { |
|
monthOrder[month] = make([]*model.GoodsOrder, 0) |
|
} |
|
monthOrder[month] = append(monthOrder[month], orders[i]) |
|
} |
|
return |
|
} |
|
|
|
// GoodsBuy buy goods from creative |
|
func (s *Service) GoodsBuy(c context.Context, mid int64, productID string, goodsType int, price int64) (err error) { |
|
date := time.Now() |
|
// 1-7号不开放兑换 |
|
if date.Day() < 8 { |
|
err = ecode.GrowupGoodsTimeErr |
|
return |
|
} |
|
p, err := s.getProduct(c, mid, productID, goodsType) |
|
if err != nil { |
|
log.Error("s.getProduct error(%v)", err) |
|
return |
|
} |
|
p.CurrentPrice = int64(dao.Round(dao.Mul(float64(p.OriginPrice), float64(p.Discount)/float64(100)), 0)) |
|
if price != p.CurrentPrice { |
|
err = ecode.GrowupPriceErr |
|
return |
|
} |
|
// check upwithdraw_income |
|
upAccount, totalUnwithdraw, err := s.getUpTotalUnwithdraw(c, mid) |
|
if err != nil { |
|
log.Error("s.getUpTotalUnwithdraw error(%v)", err) |
|
return |
|
} |
|
if totalUnwithdraw < p.CurrentPrice { |
|
err = ecode.GrowupPriceNotEnough |
|
return |
|
} |
|
uuid, err := s.sf.Generate() |
|
if err != nil { |
|
return |
|
} |
|
order := &model.GoodsOrder{ |
|
MID: mid, |
|
OrderNo: fmt.Sprintf("DHY-%s-%d-%d", date.Format("20060102150405"), uuid, mid), |
|
OrderTime: xtime.Time(date.Unix()), |
|
GoodsType: p.GoodsType, |
|
GoodsID: productID, |
|
GoodsName: p.ProductName, |
|
GoodsPrice: p.CurrentPrice, |
|
GoodsCost: p.OriginPrice, |
|
} |
|
// 清除up_summary redis缓存 |
|
if err = s.dao.DelCacheKey(c, fmt.Sprintf("growup-up-summary:%d", mid)); err != nil { |
|
log.Error("s.dao.DelCacheKey error(%v)", err) |
|
return |
|
} |
|
|
|
tx, err := s.dao.BeginTran(c) |
|
if err != nil { |
|
log.Error("s.dao.BeginTran error(%v)", err) |
|
return |
|
} |
|
// update up account |
|
rows, err := s.dao.TxUpdateUpAccountExchangeIncome(tx, mid, p.CurrentPrice, upAccount.Version) |
|
if err != nil { |
|
tx.Rollback() |
|
log.Error("s.dao.TxUpdateUpAccountExchangeIncome error(%v)", err) |
|
return |
|
} |
|
if rows != 1 { |
|
tx.Rollback() |
|
log.Error("s.dao.TxUpdateUpAccountExchangeIncome update rows(%d) != 1") |
|
err = ecode.GrowupBuyErr |
|
return |
|
} |
|
|
|
// generate order |
|
rows, err = s.dao.TxInsertGoodsOrder(tx, order) |
|
if err != nil { |
|
tx.Rollback() |
|
log.Error("s.dao.InsertGoodsOrder error(%v)", err) |
|
return |
|
} |
|
if rows != 1 { |
|
tx.Rollback() |
|
log.Error("s.dao.InsertGoodsOrder insert rows(%d) != 1", rows) |
|
err = ecode.GrowupBuyErr |
|
return |
|
} |
|
|
|
// use vip batch info |
|
if err = s.dao.ExchangeBigVIP(c, mid, p.ResourceID, uuid, _remark); err != nil { |
|
tx.Rollback() |
|
log.Error("s.dao.ExchangeBigVIP error(%v)", err) |
|
err = ecode.GrowupBuyErr |
|
return |
|
} |
|
|
|
if err = tx.Commit(); err != nil { |
|
log.Error("tx.Commit error") |
|
} |
|
return |
|
} |
|
|
|
func (s *Service) getProduct(c context.Context, mid int64, productID string, goodsType int) (p *model.GoodsInfo, err error) { |
|
p, err = s.dao.GetGoodsByProductID(c, productID, goodsType) |
|
if err != nil { |
|
log.Error("s.dao.GetGoodsByProductID error(%v)", err) |
|
return |
|
} |
|
vips, err := s.dao.ListVipProducts(c, mid) |
|
if err != nil { |
|
log.Error("s.dao.ListVipProducts error(%v)", err) |
|
return |
|
} |
|
// check ResourceID |
|
if p.ResourceID == 0 || len(vips) == 0 { |
|
err = ecode.GrowupGoodsNotExist |
|
return |
|
} |
|
vip, ok := vips[productID] |
|
if !ok { |
|
err = ecode.GrowupGoodsNotExist |
|
return |
|
} |
|
p.OriginPrice = vip.OriginPrice |
|
p.ProductName = vip.ProductName |
|
return |
|
} |
|
|
|
func (s *Service) getUpTotalUnwithdraw(c context.Context, mid int64) (upAccount *model.UpAccount, unwithdraw int64, err error) { |
|
lastDay := time.Now().AddDate(0, 0, -1) |
|
upIncomes, err := s.dao.ListUpIncome(c, mid, "up_income", lastDay.Format(_layout), lastDay.Format(_layout)) |
|
if err != nil { |
|
log.Error("s.dao.ListUpIncome error(%v)", err) |
|
return |
|
} |
|
var lastDayIncome int64 |
|
for _, up := range upIncomes { |
|
if up.Date.Time().Format(_layout) == lastDay.Format(_layout) { |
|
lastDayIncome = up.Income |
|
} |
|
} |
|
|
|
upAccount, err = s.dao.ListUpAccount(c, mid) |
|
if err != nil { |
|
log.Error("s.dao.ListUpAccount error(%v)", err) |
|
return |
|
} |
|
if upAccount == nil { |
|
err = ecode.GrowupPriceNotEnough |
|
return |
|
} |
|
unwithdraw = upAccount.TotalUnwithdrawIncome - lastDayIncome |
|
return |
|
}
|
|
|