You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

297 lines
5.2 KiB
Go

/**
* @Author: jager
* @Email: lhj168os@gmail.com
* @File: user
* @Date: 2021/12/31 2:52 下午
* @package: user
* @Version: v1.0.0
*
* @Description:
*
*/
package user
import (
"fmt"
"github.com/jageros/hawox/encrypt"
"github.com/jageros/hawox/errcode"
"github.com/jageros/hawox/redis"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"idata/internal/apity"
"idata/internal/service/user/dao"
"idata/internal/types"
"sync"
"time"
)
var (
userModel dao.UsersModel
userPool sync.Pool
)
func init() {
userPool = sync.Pool{
New: func() interface{} {
return user{}
},
}
}
func InitDao(conn sqlx.SqlConn, c cache.CacheConf) {
userModel = dao.NewUsersModel(conn, c)
}
type user struct {
data *dao.Users
}
func newUser(uid string) (*user, error) {
uData, err := userModel.FindOneByUid(uid)
if err == nil {
return nil, errcode.New(5000, "uid exist")
}
if err != dao.ErrNotFound {
return nil, err
}
uData = &dao.Users{
Uid: uid,
Phone: uid,
Openid: uid,
Secret: uid,
Score: 100,
Name: fmt.Sprintf("U_%s", uid),
}
usr := userPool.Get().(user)
usr.data = uData
return &usr, nil
}
func getRUser(uid string) (user, error) {
usr := userPool.Get().(user)
uData, err := userModel.FindOneByUid(uid)
usr.data = uData
return usr, err
}
func getRUserByPhone(phone string) (user, error) {
usr := userPool.Get().(user)
uData, err := userModel.FindOneByPhone(phone)
usr.data = uData
return usr, err
}
func getRWUser(uid string) (*user, error) {
uData, err := userModel.FindOneByUid(uid)
if err != nil {
return nil, err
}
usr := userPool.Get().(user)
usr.data = uData
return &usr, nil
}
func getRWUserByPhone(phone string) (*user, error) {
uData, err := userModel.FindOneByPhone(phone)
if err != nil {
return nil, err
}
usr := userPool.Get().(user)
usr.data = uData
return &usr, nil
}
func OperateSync(uid string, f func(u types.RWUser)) error {
var err error
err2 := redis.LockExec(uid, func(key string) {
var u *user
u, err = getRWUser(uid)
if err == nil {
f(u)
err = userModel.Update(u.data)
}
userPool.Put(*u)
})
if err2 != nil {
return err2
}
return err
}
func OperateSyncByPhone(phone string, f func(u types.RWUser)) error {
u, err := getRWUserByPhone(phone)
defer userPool.Put(*u)
if err != nil {
return err
}
err2 := redis.LockExec(u.data.Uid, func(key string) {
f(u)
err = userModel.Update(u.data)
})
if err2 != nil {
return err2
}
return err
}
func Operate(uid string, f func(u types.RUser)) error {
u, err := getRUser(uid)
if err == nil {
f(u)
}
userPool.Put(u)
return err
}
func OperateByPhone(phone string, f func(u types.RUser)) error {
u, err := getRUserByPhone(phone)
if err == nil {
f(u)
}
userPool.Put(u)
return err
}
func RegistryUser(uid string, f func(u types.RWUser)) error {
var err error
err2 := redis.LockExec(uid, func(key string) {
var u *user
u, err = newUser(uid)
if err == nil {
f(u)
_, err = userModel.Insert(u.data)
}
userPool.Put(*u)
})
if err2 != nil {
return err2
}
return err
}
// ====== Types.RUser 实现 ======
func (u user) Uid() string {
return u.data.Uid
}
func (u user) Openid() string {
if u.data.Openid == u.data.Uid {
return ""
}
return u.data.Openid
}
func (u user) Phone() string {
if u.data.Phone == u.data.Uid {
return ""
}
return u.data.Phone
}
func (u user) Secret() string {
return u.data.Secret
}
func (u user) Name() string {
return u.data.Name
}
func (u user) Gender() int64 {
return u.data.Gender
}
func (u user) Score() int64 {
return u.data.Score
}
func (u user) Avatar() string {
return u.data.Avatar
}
func (u user) VerifyPwd(pwd string) bool {
return u.data.Password == encrypt.Md5(pwd)
}
func (u user) ApiOpened(ty apity.ApiType) bool {
return int64(ty)&u.data.ApiOpened > 0
}
func (u user) ApiCanReq(ty apity.ApiType) bool {
opened := u.ApiOpened(ty)
if !opened {
return false
}
if u.IsVip() {
return true
}
return u.data.Score > 0
}
func (u user) IsVip() bool {
return u.data.Vip > 0 && u.data.VipExpireTime > time.Now().Unix()
}
func (u user) Info() map[string]interface{} {
return map[string]interface{}{
"uid": u.Uid(),
"name": u.Name(),
"gender": u.Gender(),
"avatar": u.Avatar(),
"phone": u.Phone(),
"score": u.Score(),
"vip": u.data.Vip,
"vip_expire_time": u.data.VipExpireTime,
}
}
// ========== end ==========
// ====== Types.RWUser 实现 ======
func (u *user) SetOpenid(openid string) {
u.data.Openid = openid
}
func (u *user) SetPhone(phone string) {
u.data.Phone = phone
}
func (u *user) SetSecret(secret string) {
u.data.Secret = secret
}
func (u *user) SetName(name string) {
u.data.Name = name
}
func (u *user) SetAvatar(avatar string) {
u.data.Avatar = avatar
}
func (u *user) SetGender(gender int64) {
u.data.Gender = gender
}
func (u *user) SetScore(score int64) {
u.data.Score = score
}
func (u *user) SetPassword(pwd string) {
u.data.Password = encrypt.Md5(pwd)
}
func (u *user) OpenApi(ty apity.ApiType) {
u.data.ApiOpened = u.data.ApiOpened | int64(ty)
}
func (u *user) OpenVip(duration time.Duration) {
u.data.Vip = 1
u.data.VipExpireTime = time.Now().Add(duration).Unix()
}
// ========== end ==========