This commit is contained in:
oneao committed 2025-10-31 22:35:20 +08:00
1 parent 91ae4cb474
commit b116690769
14 files changed
+669 -56

No files matched your search

@@ -3,8 +3,9 @@ package jwt
import (
"base-go-v2/internal/config"
"errors"
"github.com/golang-jwt/jwt/v5"
"time"
"github.com/golang-jwt/jwt/v5"
)
var (
@@ -29,6 +30,7 @@ func CreateToken(orgID, userID string) (string, error) {
}
expiry := config.App.JWT.Expiry
switch {
case expiry > 0:
expireAt := time.Now().Add(expiry)
@@ -0,0 +1,53 @@
package strutil
import (
"fmt"
"strconv"
)
// ToString 通用高效转换为 string
func ToString(v any) string {
switch n := v.(type) {
// 整数类型
case int:
return strconv.FormatInt(int64(n), 10)
case int8:
return strconv.FormatInt(int64(n), 10)
case int16:
return strconv.FormatInt(int64(n), 10)
case int32:
return strconv.FormatInt(int64(n), 10)
case int64:
return strconv.FormatInt(n, 10)
// 无符号整数
case uint:
return strconv.FormatUint(uint64(n), 10)
case uint8:
return strconv.FormatUint(uint64(n), 10)
case uint16:
return strconv.FormatUint(uint64(n), 10)
case uint32:
return strconv.FormatUint(uint64(n), 10)
case uint64:
return strconv.FormatUint(n, 10)
// 浮点数
case float32:
return strconv.FormatFloat(float64(n), 'f', -1, 32)
case float64:
return strconv.FormatFloat(n, 'f', -1, 64)
// 字符串
case string:
return n
// 布尔
case bool:
return strconv.FormatBool(n)
default:
// fallback
return fmt.Sprintf("%v", v)
}
}
@@ -0,0 +1,90 @@
package uid
import (
"base-go-v2/internal/config"
"sync"
"sync/atomic"
"time"
)
const (
datacenterBits = uint64(5)
workerBits = uint64(5)
sequenceBits = uint64(12)
maxSequence = -1 ^ (-1 << sequenceBits)
workerShift = sequenceBits
datacenterShift = sequenceBits + workerBits
timestampShift = sequenceBits + workerBits + datacenterBits
epoch = int64(1672531200000) // 2023-01-01
)
type Snowflake struct {
lastStamp uint64 // 上一次时间戳 (毫秒)
sequence uint64 // 序列号
dcID uint64
workerID uint64
}
var (
sfInstance *Snowflake
once sync.Once
)
// lazy 初始化实例
func initInstance() {
var dcID, wID uint64
dcID = config.App.Snowflake.DatacenterID
wID = config.App.Snowflake.WorkerID
sfInstance = &Snowflake{
dcID: dcID,
workerID: wID,
}
}
// NextID 生成全局唯一 ID,无锁版本
func NextID() uint64 {
once.Do(initInstance)
for {
now := uint64(time.Now().UnixNano() / 1e6)
last := atomic.LoadUint64(&sfInstance.lastStamp)
seq := atomic.LoadUint64(&sfInstance.sequence)
if now < last {
// 系统时钟回拨,等待
now = waitNextMillis(last)
}
if now == last {
seq = (seq + 1) & uint64(maxSequence)
if seq == 0 {
now = waitNextMillis(last)
}
} else {
seq = 0
}
if atomic.CompareAndSwapUint64(&sfInstance.lastStamp, last, now) {
atomic.StoreUint64(&sfInstance.sequence, seq)
id := ((now - uint64(epoch)) << timestampShift) |
(sfInstance.dcID << datacenterShift) |
(sfInstance.workerID << workerShift) |
seq
return id
}
}
}
// 等待下一个毫秒
func waitNextMillis(last uint64) uint64 {
now := uint64(time.Now().UnixNano() / 1e6)
for now <= last {
now = uint64(time.Now().UnixNano() / 1e6)
}
return now
}