@@ -13,83 +13,99 @@ import (
"github.com/gogf/gf/v2/os/gtime"
)
// 获取精灵信息 0是仓库,1是放生
// nextCatchTime 生成下一个唯一捕捉时间戳(原子递增 max_ts)
func ( s * PetService ) nextCatchTime ( m ... * gdb . Model ) ( uint32 , error ) {
dbm := cool . DBM ( service . NewBaseSysUserService ( ) . Model )
if len ( m ) > 0 {
dbm = m [ 0 ]
}
sql := fmt . Sprintf ( `
UPDATE %s
SET max_ts = CASE
WHEN max_ts < EXTRACT(EPOCH FROM NOW())::INT THEN EXTRACT(EPOCH FROM NOW())::INT
ELSE max_ts + 1
END
WHERE id = ? AND deleted_at IS NULL
RETURNING max_ts; ` , service . NewBaseSysUserService ( ) . Model . TableName ( ) )
ret , err := dbm . Raw ( sql , s . userid ) . All ( )
if err != nil {
return 0 , fmt . Errorf ( "生成捕捉时间失败: %w" , err )
}
arr := ret . Array ( )
if len ( arr ) == 0 {
return 0 , fmt . Errorf ( "生成捕捉时间失败: 无返回数据" )
}
return arr [ 0 ] . Uint32 ( ) , nil
}
// setCatchTime 将 Pet.CatchTime 同步到 Pet.Data.CatchTime
func setCatchTime ( pet * model . Pet ) {
if pet != nil {
pet . Data . CatchTime = pet . CatchTime
}
}
// 获取精灵信息 0是仓库,1是放生
func ( s * PetService ) PetInfo ( flag int ) [ ] model . Pet {
var tt [ ] model . Pet
err := s . dbm ( s . Model ) . Where ( "free" , flag ) . Scan ( & tt )
if err != nil {
return [ ] model . Pet { }
if err := s . dbm ( s . Model ) . Where ( "free" , flag ) . Scan ( & tt ) ; err != nil {
return nil
}
for i := 0 ; i < len ( tt ) ; i ++ {
for i := range tt {
tt [ i ] . Data . CatchTime = tt [ i ] . CatchTime
}
return tt
}
func ( s * PetService ) PetCount ( flag int ) int {
ret , err := s . dbm ( s . Model ) . Where ( "free" , flag ) . Count ( )
if err != nil {
return 0
}
return ret
}
func ( s * PetService ) UP dateFree ( ctime uint32 , free uint32 ) bool {
res , err := s . dbm ( s . Model ) . Where ( "catch_time" , ctime ) . Data (
"free" , free ,
) . Update ( )
func ( s * PetService ) Up dateFree ( catchTime , free uint32 ) bool {
res , err := s . dbm ( s . Model ) . Where ( "catch_time" , catchTime ) . Data ( "free" , free ) . Update ( )
if err != nil {
return false
}
r , _ := res . RowsAffected ( )
return r > 0
}
func ( s * PetService ) UPdatePrice ( ctime uint32 , Price uint32 , free uint32 ) error {
var item1 model . Pet
func ( s * PetService ) UpdatePrice ( catchTime , price , free uint32 ) error {
var item model . Pet
var feeRate float64
var err1 error
if free == 2 {
t , _ := s . dbm ( s . Model ) . Where ( "free" , 2 ) . Count ( )
if t > 3 {
return fmt . Errorf ( "精灵数量已满" )
}
} else {
s . dbm ( s . Model ) . Where ( "catch_time" , ctime ) . Scan ( & item1 )
_ , feeRate , err1 = item1 . GetOffShelfFee ( )
if err1 != nil {
return err1
if err := s . dbm ( s . Model ) . Where ( "catch_time" , catchTime ) . Scan ( & item ) ; err != nil {
return err
}
_ , feeRate , _ = item . GetOffShelfFee ( )
_ = feeRate // feeRate 仅在 non-2 分支使用,在此声明以统一作用域
}
res , _ := s . dbm ( s . Model ) .
Where ( "catch_tim e", ctime ) . // 限定 ctime, 避免全表更新
//Where("sale_price = ?", 0). // 只筛选 sale_price=0 的记录
Data ( g . Map {
"sale_price" : Price ,
"free" : fr ee,
} ) . Update ( )
g , _ := res . RowsAffected ( )
if g > 0 && free != 2 && feeRate != 0 {
amount1 := item1 . CalculateOffShelfAmount ( feeRate )
service . NewBaseSysUserService ( ) . UpdateFreeGold ( s . userid , - int64 ( amount1 * 100 ) )
res , _ := s . dbm ( s . Model ) . Where ( "catch_time" , catchTime ) . Data ( g . Map {
"sale_pric e": price ,
"free" : free ,
} ) . Update ( )
affected , _ := res . RowsAffected ( )
if affected > 0 && free != 2 && feeRate != 0 {
amount := item . CalculateOffShelfAmount ( feeRate )
service . NewBaseSysUserService ( ) . UpdateFreeGold ( s . userid , - int64 ( amount * 100 ) )
}
return nil
}
func ( s * PetService ) BuyPet ( pid uint32 ) error {
tt := NewPetService ( 0 ) . PetInfo_One_ID ( pid )
func ( s * PetService ) BuyPet ( pid uint32 ) error {
tt := NewPetService ( 0 ) . PetInfoOneByID ( pid )
if tt == nil {
return fmt . Errorf ( "没有此精灵" )
}
@@ -105,192 +121,136 @@ func (s *PetService) BuyPet(pid uint32) error {
if ! tt . UpdateTime . AddDate ( 0 , 0 , 1 ) . Before ( gtime . Now ( ) ) {
return fmt . Errorf ( "未到购买时间" )
}
return g . DB ( ) . Transaction ( context . TODO ( ) , func ( ctx context . Context , tx gdb . TX ) error {
useGold := int64 ( tt . SalePrice ) * 102 + int64 ( tt . SaleCount ) * 5
var user basemodel . BaseSysUser
useglod := int64 ( tt . SalePrice ) * 102 + int64 ( tt . SaleCount ) * 5
var res1 basemodel . BaseSysUser
err := tx . Model ( basemodel . BaseSysUser { } ) . Where ( "id" , s . userid ) . Fields ( "free_gold" ) . Scan ( & res1 )
if err != nil {
if err := tx . Model ( basemodel . BaseSysUser { } ) . Where ( "id" , s . userid ) . Fields ( "free_gold" ) . Scan ( & user ) ; err != nil {
return err
}
if res1 . FreeGold < useglo d {
if user . FreeGold < useGol d {
return fmt . Errorf ( "余额不足" )
}
_ , err = tx . Model ( basemodel . BaseSysUser { } ) . Where ( "id" , s . userid ) . Increment ( "free_gold" , - useglod )
if err != nil {
return err
}
res , err := tx . Model ( s . Model ) . Where ( "id" , tt . ID ) . Delete ( )
if _ , err := tx . Model ( basemodel . BaseSysUser { } ) . Where ( "id" , s . userid ) . Increment ( "free_gold" , - useGold ) ; err != nil {
return err
}
res , err := tx . Model ( s . Model ) . Where ( "id" , tt . ID ) . Delete ( )
if err != nil {
return err
}
c d, _ := res . RowsAffected ( )
if c d == 0 {
affecte d, _ := res . RowsAffected ( )
if affecte d == 0 {
return fmt . Errorf ( "重复订单" )
}
_ , err = tx . Model ( basemodel . BaseSysUser { } ) . Where ( "id" , tt . PlayerID ) . Increment ( "free_gold" , int64 ( tt . SalePrice ) * 98 )
if _ , err := tx . Model ( basemodel . BaseSysUser { } ) . Where ( "id" , tt . PlayerID ) . Increment ( "free_gold" , int64 ( tt . SalePrice ) * 98 ) ; err != nil {
return err
}
catchTime , err := s . nextCatchTime ( tx . Model ( service . NewBaseSysUserService ( ) . Model ) )
if err != nil {
return err
}
sql := fmt . Sprintf ( `
UPDATE %s
SET max_ts = CASE
WHEN max_ts < EXTRACT(EPOCH FROM NOW())::INT THEN EXTRACT(EPOCH FROM NOW())::INT
ELSE max_ts + 1
END
WHERE id = ? AND deleted_at IS NULL
RETURNING max_ts;
` , service . NewBaseSysUserService ( ) . Model . TableName ( ) )
// 执行 Raw SQL 并扫描返回值
ret , err := tx . Model ( service . NewBaseSysUserService ( ) . Model ) . Raw ( sql , s . userid ) . All ( )
if err != nil {
return err
player := model . Pet {
PlayerID : s . userid ,
Data : tt . Data ,
CatchTime : catchTime ,
Free : 0 ,
SalePrice : tt . SalePrice ,
SaleCount : tt . SaleCount + 1 ,
}
//fmt.Println(ret, err)
tt . CatchTime = ret . Array ( ) [ 0 ] . Uint32 ( )
var player model . Pet
player . PlayerID = s . userid
player . Data = tt . Data
player . Data . OldCatchTime = 0
player . CatchTime = tt . CatchTime
player . Free = 0
player . SalePrice = tt . SalePrice
player . SaleCount = tt . SaleCount + 1
player . IsVip = cool . Config . ServerInfo . IsVip
player . Data . OldCatchTime = 0
_ , err = tx . Model ( s . Model ) . Insert ( player )
if err != nil {
if _ , err : = tx . Model ( s . Model ) . Insert ( player ) ; err != nil {
return err
}
return nil
} )
}
func ( s * PetService ) UPdate ( t model . PetInfo ) bool {
func ( s * PetService ) Update ( t model . PetInfo ) bool {
_ , err := s . dbm ( s . Model ) . Where ( "catch_time" , t . CatchTime ) . Data ( "data" , t ) . Update ( )
return err == nil
}
func ( s * PetService ) PetInfo_One ( cachetime uint32 ) * model . Pet {
m := s . dbm ( s . Model ) . Wher e ( " catch_t ime" , cachetime )
func ( s * PetService ) PetInfoOneByCatchTim e( catchT ime uint32 ) * model . Pet {
var tt * model . Pet
m . Scan ( & tt )
if tt == nil {
if err := s . dbm ( s . Model ) . Where ( "catch_time" , catchTime ) . Scan ( & tt ) ; err != nil || tt == nil {
return nil
}
tt . Data . CatchTime = tt . CatchTime
setCatchTime ( tt )
return tt
}
func ( s * PetService ) PetInfo_One_ID ( Pid uint32 ) * model . Pet {
m := s . dbm ( s . Model ) . Where ( "id" , Pid )
func ( s * PetService ) PetInfoOneByID ( id uint32 ) * model . Pet {
var tt * model . Pet
m . Scan ( & tt )
if tt == nil {
if err := s . dbm ( s . Model ) . Where ( "id" , id ) . Scan ( & tt ) ; err != nil || tt == nil {
return nil
}
tt . Data . CatchTime = tt . CatchTime
setCatchTime ( tt )
return tt
}
func ( s * PetService ) PetInfo_One_ohter ( userid , cachetime uint32 ) model . Pet {
m := s . dbm ( s . Model ) . W here ( " catch_t ime" , cachetime )
func ( s * PetService ) PetInfoOneOt her( userid , catchT ime uint32 ) model . Pet {
var tt model . Pet
m . Scan ( & tt )
s . dbm ( s . Model ) . Where ( "catch_time" , catchTime ) . Scan ( & tt )
tt . Data . CatchTime = tt . CatchTime
return tt
}
func ( s * PetService ) PetInfo_One_Unscoped ( cachetime uint32 ) * model . Pet {
m := s . dbm ( s . Model ) . Where ( " catch_t ime" , cachetime ) . Unscoped ( )
func ( s * PetService ) PetInfoOneUnscoped ( catchT ime uint32 ) * model . Pet {
var tt * model . Pet
m . Scan ( & tt )
if tt == nil {
if err := s . dbm ( s . Model ) . Where ( "catch_time" , catchTime ) . Unscoped ( ) . Scan ( & tt ) ; err != nil || tt == nil {
return nil
}
tt . Data . CatchTime = tt . CatchTime
setCatchTime ( tt )
return tt
}
func ( s * PetService ) Pet_del ( cachetime uint32 ) {
s . dbm ( s . Model ) . Where ( "catch_time" , cachetime ) . Delete ( )
func ( s * PetService ) PetDel ( catchTime uint32 ) {
s . dbm ( s . Model ) . Where ( "catch_time" , catchTime ) . Delete ( )
}
func ( s * PetService ) Pet_LEVEL_all ( ) [ ] model . Pet {
func ( s * PetService ) PetLevelAll ( ) [ ] model . Pet {
var tt [ ] model . Pet
s . dbm ( s . Model ) . As ( "pp" ) . Wheref ( ` (pp.data->>'Level')::INT > 100` ) . OrderDesc ( "(pp.data->>'Level')::INT" ) . Scan ( & tt )
s . dbm ( s . Model ) . As ( "pp" ) .
Wheref ( " (pp.data->>'Level')::INT > 100" ) .
OrderDesc ( "(pp.data->>'Level')::INT" ) .
Scan ( & tt )
return tt
}
// 精灵真正添加后的捕捉时间才是真正的时间
func ( s * PetService ) PetAdd ( y * model . PetInfo , salec ount uint32 ) uint32 {
// PetAdd 精灵真正添加后的捕捉时间才是真正的时间
func ( s * PetService ) PetAdd ( y * model . PetInfo , saleC ount uint32 ) uint32 {
if y == nil {
return 0
}
sql := fmt . Sprintf ( `
UPDATE %s
SET max_ts = CASE
WHEN max_ts < EXTRACT(EPOCH FROM NOW())::INT THEN EXTRACT(EPOCH FROM NOW())::INT
ELSE max_ts + 1
END
WHERE id = ? AND deleted_at IS NULL
RETURNING max_ts;
` , service . NewBaseSysUserService ( ) . Model . TableName ( ) )
// 执行 Raw SQL 并扫描返回值
ret , _ := cool . DBM ( service . NewBaseSysUserService ( ) . Model ) . Raw ( sql , s . userid ) . All ( )
//fmt.Println(ret, err)
y . CatchTime = ret . Array ( ) [ 0 ] . Uint32 ( )
m1 := cool . DBM ( s . Model ) . Where ( "player_id" , s . userid )
var player model . Pet
player . PlayerID = s . userid
player . Data = * y
player . CatchTime = y . CatchTime
player . Free = 0
player . SaleCount = salecount
player . IsVip = cool . Config . ServerInfo . IsVip
_ , err := m1 . Insert ( player )
catchTime , err := s . nextCatchTime ( )
if err != nil {
panic ( err )
return 0
}
return y . CatchTime
y . CatchTime = catchTime
player := model . Pet {
PlayerID : s . userid ,
Data : * y ,
CatchTime : catchTime ,
Free : 0 ,
SaleCount : saleCount ,
}
player . IsVip = cool . Config . ServerInfo . IsVip
if _ , err := cool . DBM ( s . Model ) . Where ( "player_id" , s . userid ) . Insert ( player ) ; err != nil {
return 0
}
return catchTime
}
// func (s *PetService) ModifyBefore(ctx context.Context, method string, param map[string]interface{}) (err error) {
// admin := cool.GetAdmin(ctx)
// userId := admin.UserId
// s.userid = uint32(userId)
// // if method == "Update" {
// // if gconv.Uint(param["free"]) != 0 {
// // err = fmt.Errorf("修改失败")
// // }
// // if userId != gconv.Uint(param["player_id"]) {
// // err = fmt.Errorf("修改失败")
// // }
// // }
// return
// }
type PetService struct {
BaseService
}
@@ -305,29 +265,20 @@ func NewPetService(userid uint32) *PetService {
AddOrderby : g . MapStrStr { "updateTime" : "asc" } ,
FieldEQ : [ ] string { "player_id" , "free" } ,
Where : func ( ctx context . Context ) [ ] [ ] interface { } {
return [ ] [ ] interface { } {
{ "free" , 0 , false } ,
{ "is_vip" , 0 , true } ,
}
} ,
} ,
PageQueryOp : & cool . QueryOp {
FieldEQ : [ ] string { "player_id" , "free" } ,
DataFieldEQ : [ ] string { "ID" } ,
Where : func ( ctx context . Context ) [ ] [ ] interface { } {
// var (
// admin = cool.GetAdmin(ctx)
// // userId = admin.UserId
// )
return [ ] [ ] interface { } {
// {"player_id", userId, true},
{ "free" , 0 , false } ,
{ "is_vip" , 0 , true } ,
}
} ,
} ,
} ,