This commit is contained in:
@@ -2,20 +2,48 @@ package service
|
||||
|
||||
import (
|
||||
"blazing/cool"
|
||||
basemodel "blazing/modules/base/model"
|
||||
"blazing/modules/base/service"
|
||||
"blazing/modules/player/model"
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/grand"
|
||||
)
|
||||
|
||||
type GoldListService struct {
|
||||
BaseService
|
||||
}
|
||||
|
||||
func (s *GoldListService) getPrevDayAvgRate() float64 {
|
||||
var (
|
||||
now = gtime.Now()
|
||||
yesterday = now.AddDate(0, 0, -1)
|
||||
dayStart = gtime.NewFromStr(yesterday.Format("Y-m-d") + " 00:00:00")
|
||||
nextDay = dayStart.AddDate(0, 0, 1)
|
||||
result struct {
|
||||
AvgRate float64 `json:"avg_rate"`
|
||||
}
|
||||
)
|
||||
|
||||
err := s.dbm_fix(s.Model).
|
||||
Fields("COALESCE(AVG(rate), 0) AS avg_rate").
|
||||
Where("status", 1).
|
||||
WhereGTE("createTime", dayStart).
|
||||
WhereLT("createTime", nextDay).
|
||||
Scan(&result)
|
||||
if err != nil || result.AvgRate <= 0 {
|
||||
return 1
|
||||
}
|
||||
|
||||
return result.AvgRate
|
||||
}
|
||||
|
||||
func (s *GoldListService) ModifyBefore(ctx context.Context, method string, param map[string]interface{}) (err error) {
|
||||
admin := cool.GetAdmin(ctx)
|
||||
userId := admin.UserId
|
||||
@@ -29,14 +57,16 @@ func (s *GoldListService) ModifyBefore(ctx context.Context, method string, param
|
||||
if t > 0 {
|
||||
return fmt.Errorf("不允许多挂单")
|
||||
}
|
||||
if gconv.Float64(param["rate"]) > 2 {
|
||||
r := g.List{}
|
||||
for i := 0; i < grand.N(1, 3); i++ {
|
||||
r = append(r, g.Map{"rate": param["rate"], "exchange_num": param["exchange_num"], "player_id": 10001})
|
||||
}
|
||||
|
||||
s.dbm_fix(s.Model).Data(r).Insert()
|
||||
var (
|
||||
rate = gconv.Float64(param["rate"])
|
||||
prevAvg = s.getPrevDayAvgRate()
|
||||
minRate = math.Round(prevAvg*0.9*10000) / 10000
|
||||
maxRate = math.Round(prevAvg*1.1*10000) / 10000
|
||||
)
|
||||
|
||||
if rate < minRate || rate > maxRate {
|
||||
return fmt.Errorf("当前价格涨跌幅超限,需在昨日均价 %.4f 的上下10%%范围内(%.4f - %.4f)", prevAvg, minRate, maxRate)
|
||||
}
|
||||
} else {
|
||||
var items []model.GoldBeanOrder
|
||||
@@ -70,6 +100,100 @@ func (s *GoldListService) Done(listid uint32) (*model.GoldBeanOrder, error) {
|
||||
}
|
||||
return &rr, nil
|
||||
}
|
||||
|
||||
func (s *GoldListService) Trade(ctx context.Context, listid uint32, buyerID uint32) (*model.GoldBeanOrder, error) {
|
||||
var result *model.GoldBeanOrder
|
||||
|
||||
err := g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||
var (
|
||||
order model.GoldBeanOrder
|
||||
buyer basemodel.BaseSysUser
|
||||
seller basemodel.BaseSysUser
|
||||
)
|
||||
|
||||
if err := tx.Model(s.Model).Where("id", listid).Where("status", 0).Scan(&order); err != nil {
|
||||
return err
|
||||
}
|
||||
if order.ID == 0 {
|
||||
return fmt.Errorf("重复订单")
|
||||
}
|
||||
|
||||
if !order.UpdateTime.Add(1 * time.Hour).Before(gtime.Now()) {
|
||||
return fmt.Errorf("未到购买时间")
|
||||
}
|
||||
|
||||
costFree := int64(math.Round(order.Rate * float64(order.ExchangeNum) * 100))
|
||||
sellerGold := int64(order.ExchangeNum) * 100
|
||||
sellerIncome := int64(math.Round(order.Rate * float64(order.ExchangeNum) * 95))
|
||||
buyerGold := int64(order.ExchangeNum * 95)
|
||||
|
||||
if err := tx.Model(basemodel.BaseSysUser{}).Where("id", buyerID).Fields("free_gold").Scan(&buyer); err != nil {
|
||||
return err
|
||||
}
|
||||
if buyer.FreeGold < costFree {
|
||||
return fmt.Errorf("余额不足")
|
||||
}
|
||||
|
||||
if err := tx.Model(basemodel.BaseSysUser{}).Where("id", order.PlayerID).Fields("goldbean").Scan(&seller); err != nil {
|
||||
return err
|
||||
}
|
||||
if seller.GoldBean < sellerGold {
|
||||
return fmt.Errorf("卖家余额不足")
|
||||
}
|
||||
|
||||
res, err := tx.Model(basemodel.BaseSysUser{}).
|
||||
Where("id", buyerID).
|
||||
WhereGTE("free_gold", costFree).
|
||||
Increment("free_gold", -costFree)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, _ := res.RowsAffected()
|
||||
if rows == 0 {
|
||||
return fmt.Errorf("余额不足")
|
||||
}
|
||||
|
||||
res, err = tx.Model(basemodel.BaseSysUser{}).
|
||||
Where("id", order.PlayerID).
|
||||
WhereGTE("goldbean", sellerGold).
|
||||
Increment("goldbean", -sellerGold)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, _ = res.RowsAffected()
|
||||
if rows == 0 {
|
||||
return fmt.Errorf("卖家余额不足")
|
||||
}
|
||||
|
||||
if _, err = tx.Model(basemodel.BaseSysUser{}).Where("id", order.PlayerID).Increment("free_gold", sellerIncome); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = tx.Model(basemodel.BaseSysUser{}).Where("id", buyerID).Increment("goldbean", buyerGold); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err = tx.Model(s.Model).
|
||||
Data("status", 1).
|
||||
Where("id", listid).
|
||||
Where("status", 0).
|
||||
Update()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, _ = res.RowsAffected()
|
||||
if rows == 0 {
|
||||
return fmt.Errorf("重复订单")
|
||||
}
|
||||
|
||||
result = &order
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
func (s *GoldListService) Get() []model.GoldBeanOrder {
|
||||
var rr []model.GoldBeanOrder
|
||||
s.dbm_fix(s.Model).Where("status", 0).Order("rate", "asc").Scan(&rr)
|
||||
|
||||
Reference in New Issue
Block a user