150 lines
3.8 KiB
Go
150 lines
3.8 KiB
Go
package cacherepo
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/go-redis/redis/v8"
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
"mingyang-admin-app-rpc/internal/svc"
|
|
"time"
|
|
)
|
|
|
|
type CacheRepository struct {
|
|
ctx context.Context
|
|
svcCtx *svc.ServiceContext
|
|
logx.Logger
|
|
}
|
|
|
|
func NewCacheRepository(ctx context.Context, svcCtx *svc.ServiceContext) *CacheRepository {
|
|
return &CacheRepository{
|
|
ctx: ctx,
|
|
svcCtx: svcCtx,
|
|
Logger: logx.WithContext(ctx),
|
|
}
|
|
}
|
|
|
|
// SetVerificationCode 设置验证码
|
|
func (r *CacheRepository) SetVerificationCode(ctx context.Context, key, code string, expiry time.Duration) error {
|
|
data := VerificationCodeData{
|
|
Code: code,
|
|
Attempts: 0,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
|
|
jsonData, err := json.Marshal(data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return r.svcCtx.Redis.Set(ctx, key, jsonData, expiry).Err()
|
|
}
|
|
|
|
// GetVerificationCode 获取验证码
|
|
func (r *CacheRepository) GetVerificationCode(ctx context.Context, key string) (*VerificationCodeData, error) {
|
|
data, err := r.svcCtx.Redis.Get(ctx, key).Result()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var codeData VerificationCodeData
|
|
if err := json.Unmarshal([]byte(data), &codeData); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &codeData, nil
|
|
}
|
|
|
|
// IncrementVerificationAttempts 增加验证尝试次数
|
|
func (r *CacheRepository) IncrementVerificationAttempts(ctx context.Context, key string) error {
|
|
data, err := r.GetVerificationCode(ctx, key)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if data == nil {
|
|
return fmt.Errorf("verification code.proto not found")
|
|
}
|
|
|
|
data.Attempts++
|
|
jsonData, err := json.Marshal(data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 重新设置过期时间
|
|
ttl := r.svcCtx.Redis.TTL(ctx, key).Val()
|
|
return r.svcCtx.Redis.Set(ctx, key, jsonData, ttl).Err()
|
|
}
|
|
|
|
// DeleteVerificationCode 删除验证码
|
|
func (r *CacheRepository) DeleteVerificationCode(ctx context.Context, key string) error {
|
|
return r.svcCtx.Redis.Del(ctx, key).Err()
|
|
}
|
|
|
|
// SetPasswordResetToken 设置密码重置令牌
|
|
func (r *CacheRepository) SetPasswordResetToken(ctx context.Context, key, token string, expiry time.Duration) error {
|
|
return r.svcCtx.Redis.Set(ctx, key, token, expiry).Err()
|
|
}
|
|
|
|
// GetPasswordResetToken 获取密码重置令牌
|
|
func (r *CacheRepository) GetPasswordResetToken(ctx context.Context, key string) (string, error) {
|
|
return r.svcCtx.Redis.Get(ctx, key).Result()
|
|
}
|
|
|
|
// DeletePasswordResetToken 删除密码重置令牌
|
|
func (r *CacheRepository) DeletePasswordResetToken(ctx context.Context, key string) error {
|
|
return r.svcCtx.Redis.Del(ctx, key).Err()
|
|
}
|
|
|
|
// SetSession 设置会话
|
|
func (r *CacheRepository) SetSession(ctx context.Context, key string, data interface{}, expiry time.Duration) error {
|
|
jsonData, err := json.Marshal(data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return r.svcCtx.Redis.Set(ctx, key, jsonData, expiry).Err()
|
|
}
|
|
|
|
// GetSession 获取会话
|
|
func (r *CacheRepository) GetSession(ctx context.Context, key string, result interface{}) error {
|
|
data, err := r.svcCtx.Redis.Get(ctx, key).Result()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return json.Unmarshal([]byte(data), result)
|
|
}
|
|
|
|
// DeleteSession 删除会话
|
|
func (r *CacheRepository) DeleteSession(ctx context.Context, key string) error {
|
|
return r.svcCtx.Redis.Del(ctx, key).Err()
|
|
}
|
|
|
|
// RateLimit 限流
|
|
func (r *CacheRepository) RateLimit(ctx context.Context, key string, limit int, window time.Duration) (bool, error) {
|
|
count, err := r.svcCtx.Redis.Get(ctx, key).Int()
|
|
if err != nil && !errors.Is(err, redis.Nil) {
|
|
return false, err
|
|
}
|
|
|
|
if count >= limit {
|
|
return false, nil
|
|
}
|
|
|
|
pipe := r.svcCtx.Redis.Pipeline()
|
|
pipe.Incr(ctx, key)
|
|
pipe.Expire(ctx, key, window)
|
|
|
|
_, err = pipe.Exec(ctx)
|
|
return err == nil, err
|
|
}
|
|
|
|
// VerificationCodeData 数据模型
|
|
type VerificationCodeData struct {
|
|
Code string `json:"code.proto"`
|
|
Attempts int `json:"attempts"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|