/** * @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 ==========