user.go 3.13 KB
Newer Older
chenweijian's avatar
chenweijian committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
package user_c

import (
	redisV8 "github.com/go-redis/redis/v8"
	"github.com/jinzhu/copier"
	"hilo-user/_const/redis_key/user_k"
	"hilo-user/domain"
	"hilo-user/domain/cache"
	"hilo-user/domain/model/user_m"
	"hilo-user/myerr"
	"hilo-user/myerr/bizerr"
	"hilo-user/resource/mysql"
)

// 获取用户简要信息
// param userId 用户id
func GetUserTinyById(model *domain.Model, userId mysql.ID) (*user_m.UserTiny, error) {
	userTiny := new(user_m.UserTiny)
	key := user_k.GetUserTinyKey(userId)
	err := cache.GetJSON(model, key, userTiny)
	if err != nil && err != redisV8.Nil {
		return nil, err
	}
	if err == redisV8.Nil {
		// cache miss,get from mysql
		if user, err := user_m.GetUser(model, userId); err != nil {
			return nil, err
		} else {
			copier.Copy(userTiny, user)
			err = cacheUserTiny(model, user)
			if err != nil {
				return nil, err
			}
		}
	}
	return userTiny, nil
}

// 获取用户简要信息By ExternalId
func GetUserByExternalId(model *domain.Model, externalId mysql.Str) (*user_m.UserTiny, error) {
	userId, err := ToUserId(model, externalId)
	if err != nil {
		return nil, err
	}
	return GetUserTinyById(model, userId)
}

// externalId 到 userId
func ToUserId(model *domain.Model, externalId mysql.Str) (mysql.ID, error) {
	if externalId == "" {
		return 0, myerr.NewSysError("externalId 不能为空")
	}
	userId, err := model.Redis.Get(model.Context, user_k.GetExternalIdToUidKey(externalId)).Int64()
	if err != nil && err != redisV8.Nil {
		return 0, err
	}
	// cache miss,sync from db
	if err == redisV8.Nil {
		if user, err := user_m.GetUserByExtId(model, externalId); err != nil {
			return 0, bizerr.ExternalIdNoExist
		} else {
			if err = cacheUserTiny(model, user); err != nil {
				return 0, err
			}
			userId = int64(user.ID)
		}
	}
	return mysql.ID(userId), nil
}

// code 到 userId
func ToUserIdByCode(model *domain.Model, code mysql.Str) (mysql.ID, error) {
	if code == "" {
		return 0, myerr.NewSysError("code 不能为空")
	}
	userId, err := model.Redis.Get(model.Context, user_k.GetCodeToUidKey(code)).Int64()
	if err != nil && err != redisV8.Nil {
		return 0, err
	}
	// cache miss,sync from db
	if err == redisV8.Nil {
		if user, err := user_m.GetUserByCode(model, code); err != nil {
			return 0, bizerr.CodeNoExist
		} else {
			if err = cacheUserTiny(model, user); err != nil {
				return 0, err
			}
			userId = int64(user.ID)
		}
	}
	return mysql.ID(userId), nil
}

// 缓存userTiny
// 顺手缓存externalId->userId
// 顺手缓存code->userId
// param user: 已经在上层获取的db User结构
func cacheUserTiny(model *domain.Model, user *user_m.User) error {
	userTiny := new(user_m.UserTiny)
	if err := copier.Copy(userTiny, user); err != nil {
		return err
	}
	// cache externalId->userId
	if err := model.Redis.SetEX(model.Context, user_k.GetExternalIdToUidKey(user.ExternalId), user.ID, cache.GetDefaultTTL()).Err(); err != nil {
		return err
	}
	// cache code->userId
	if err := model.Redis.SetEX(model.Context, user_k.GetCodeToUidKey(user.Code), user.ID, cache.GetDefaultTTL()).Err(); err != nil {
		return err
	}
	if err := cache.SetJSON(model, user_k.GetUserTinyKey(user.ID), userTiny); err != nil {
		return err
	}
	return nil
}