app-cloudep-member-server/internal/usecase/uid_generate.go

77 lines
1.8 KiB
Go
Raw Normal View History

package usecase
import (
"app-cloudep-member-server/internal/domain"
"app-cloudep-member-server/internal/domain/usecase"
mgo "app-cloudep-member-server/internal/model/mongo"
"context"
"math"
"strconv"
"strings"
)
type GenerateUseCaseParam struct {
GenerateUIDRepo mgo.AutoIdModel
}
type GenerateUseCase struct {
generateUIDRepo mgo.AutoIdModel
}
func MustGenerateUseCase(param GenerateUseCaseParam) usecase.UIDGenerateUseCase {
return &GenerateUseCase{
generateUIDRepo: param.GenerateUIDRepo,
}
}
// Generate 利用 mongo 創立全局唯一的 ark id
// TODO 如果之後有效能問題,扛在同一個 mongo 資料庫,在改成雪花算法
func (g GenerateUseCase) Generate(ctx context.Context) (string, error) {
var data mgo.AutoId
err := g.generateUIDRepo.Inc(ctx, &data)
if err != nil {
return "", err
}
uid := strconv.Itoa(int(domain.InitAutoId + data.Counter))
code, err := generateReferralCode(uid)
if err != nil {
return "", err
}
return code, nil
}
// generateReferralCode 從 UID 生成 referralCode
func generateReferralCode(uid string) (string, error) {
uidInt, err := strconv.ParseInt(uid, 10, 64)
if err != nil {
return "", err
}
maxReferralUIDBoundary := int64(math.Pow(float64(len(domain.ConvertTable)), float64(domain.DefaultReferralCodeLen)))
if uidInt > maxReferralUIDBoundary {
return "", usecase.UIDOutOfRangeErrorCodeError("uid encode out of range")
}
encoded := encodeToBase(uidInt, 10, domain.DefaultReferralCodeLen)
return encoded, nil
}
func encodeToBase(num int64, base int, length int) string {
result := ""
for num > 0 {
index := num % int64(base)
result = domain.ConvertTable[index] + result
num /= int64(base)
}
// makes sure the length fo result feats the input length
if len(result) < length {
result = strings.Repeat(domain.ConvertTable[0], length-len(result)) + result
}
return result
}