Files
go-common/app/interface/main/growup/service/exchange.go
2019-04-22 18:49:16 +08:00

251 lines
6.4 KiB
Go

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
}