124 lines
2.7 KiB
Go
124 lines
2.7 KiB
Go
package svc
|
||
|
||
import (
|
||
"bytes"
|
||
"errors"
|
||
"math/rand"
|
||
"net/rpc"
|
||
"sync"
|
||
|
||
"github.com/globalsign/mgo"
|
||
"github.com/globalsign/mgo/bson"
|
||
"mongo.games.com/game/dbproxy/mongo"
|
||
"mongo.games.com/game/model"
|
||
)
|
||
|
||
/*
|
||
邀请码生成规则
|
||
1. 邀请码长度为8位,由数字和字母组成
|
||
2. 0-9,a-z,A-Z随机组合
|
||
*/
|
||
|
||
var (
|
||
InviteCodeDBName = "user"
|
||
InviteCodeCollName = "user_icode"
|
||
InviteCodeColError = errors.New("InviteCode collection open failed")
|
||
InviteCodeMutex = sync.Mutex{}
|
||
)
|
||
|
||
func InviteCodeCollection(plt string) *mongo.Collection {
|
||
s := mongo.MgoSessionMgrSington.GetPltMgoSession(plt, InviteCodeDBName)
|
||
if s != nil {
|
||
c, first := s.DB().C(InviteCodeCollName)
|
||
if first {
|
||
c.EnsureIndex(mgo.Index{Key: []string{"snid"}, Unique: true, Background: true, Sparse: true})
|
||
c.EnsureIndex(mgo.Index{Key: []string{"code"}, Unique: true, Background: true, Sparse: true})
|
||
}
|
||
return c
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
func GetInviteCode(plt string, snid int32) (string, error) {
|
||
c := InviteCodeCollection(plt)
|
||
if c == nil {
|
||
return "", InviteCodeColError
|
||
}
|
||
|
||
col := new(model.InviteCode)
|
||
err := c.Find(bson.M{"snid": snid}).One(col)
|
||
notFound := errors.Is(err, mgo.ErrNotFound)
|
||
if err != nil && !notFound {
|
||
return "", err
|
||
}
|
||
|
||
if notFound || col.Code == "" {
|
||
InviteCodeMutex.Lock()
|
||
defer InviteCodeMutex.Unlock()
|
||
// 创建
|
||
var n int
|
||
for i := 0; i < 100; i++ {
|
||
code := getInviteCode(8)
|
||
n, err = c.Find(bson.M{"code": code}).Count()
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
if n > 0 {
|
||
continue
|
||
}
|
||
col.Id = bson.NewObjectId()
|
||
col.SnId = snid
|
||
col.Code = code
|
||
_, err = c.Upsert(bson.M{"snid": snid}, col)
|
||
break
|
||
}
|
||
}
|
||
|
||
return col.Code, err
|
||
}
|
||
|
||
const StringList = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||
|
||
func getInviteCode(n int) string {
|
||
b := bytes.NewBuffer(make([]byte, 0, n))
|
||
for i := 0; i < n; i++ {
|
||
b.WriteByte(StringList[rand.Intn(len(StringList))])
|
||
}
|
||
return b.String()
|
||
}
|
||
|
||
type InviteCodeSvc struct {
|
||
}
|
||
|
||
func (i *InviteCodeSvc) GetSnIdByCode(req *model.InviteSnIdReq, ret *model.InviteSnIdRet) error {
|
||
c := InviteCodeCollection(req.Platform)
|
||
if c == nil {
|
||
return InviteCodeColError
|
||
}
|
||
col := new(model.InviteCode)
|
||
err := c.Find(bson.M{"code": req.Code}).One(col)
|
||
if err != nil && !errors.Is(err, mgo.ErrNotFound) {
|
||
return err
|
||
}
|
||
ret.SnId = col.SnId
|
||
return nil
|
||
}
|
||
|
||
func GetCodeBySnId(platform string, snid int32) (string, error) {
|
||
c := InviteCodeCollection(platform)
|
||
if c == nil {
|
||
return "", InviteCodeColError
|
||
}
|
||
col := new(model.InviteCode)
|
||
err := c.Find(bson.M{"snid": snid}).One(col)
|
||
if err != nil && !errors.Is(err, mgo.ErrNotFound) {
|
||
return "", err
|
||
}
|
||
return col.Code, err
|
||
}
|
||
|
||
func init() {
|
||
rpc.Register(new(InviteCodeSvc))
|
||
}
|