251 lines
6.4 KiB
Go
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
|
|
}
|