初始化2

This commit is contained in:
2026-07-10 17:33:33 +08:00
parent b51ee98afa
commit 94f6ecf901
59 changed files with 3893 additions and 980 deletions

103
server/utils/log_buffer.go Normal file
View File

@@ -0,0 +1,103 @@
package utils
import (
"fmt"
"io"
"os"
"sync"
"time"
)
// LogEntry 日志条目
type LogEntry struct {
Time time.Time `json:"time"`
Level string `json:"level"`
Message string `json:"message"`
}
// LogBuffer 环形日志缓冲区
type LogBuffer struct {
mu sync.RWMutex
entries []LogEntry
maxSize int
writer io.Writer // 原始输出(控制台)
}
var LogBuf = NewLogBuffer(2000)
func NewLogBuffer(maxSize int) *LogBuffer {
return &LogBuffer{
entries: make([]LogEntry, 0, maxSize),
maxSize: maxSize,
writer: os.Stderr,
}
}
// Write 实现 io.Writer 接口, 用于 log.SetOutput
func (b *LogBuffer) Write(p []byte) (n int, err error) {
// 写入原始输出
b.writer.Write(p)
msg := string(p)
level := "INFO"
switch {
case contains(msg, "FAIL") || contains(msg, "Error") || contains(msg, "error"):
level = "ERROR"
case contains(msg, "WARN") || contains(msg, "warn"):
level = "WARN"
}
b.mu.Lock()
b.entries = append(b.entries, LogEntry{
Time: time.Now(),
Level: level,
Message: msg,
})
// 超过上限则截掉前半部分
if len(b.entries) > b.maxSize {
b.entries = b.entries[len(b.entries)-b.maxSize:]
}
b.mu.Unlock()
return len(p), nil
}
// Get 获取最近 n 条日志
func (b *LogBuffer) Get(n int) []LogEntry {
b.mu.RLock()
defer b.mu.RUnlock()
total := len(b.entries)
if n <= 0 || n > total {
n = total
}
result := make([]LogEntry, n)
copy(result, b.entries[total-n:])
return result
}
// Count 日志总数
func (b *LogBuffer) Count() int {
b.mu.RLock()
defer b.mu.RUnlock()
return len(b.entries)
}
func contains(s, sub string) bool {
return len(s) >= len(sub) && (s == sub || len(s) > 0 && findSubstring(s, sub))
}
func findSubstring(s, sub string) bool {
for i := 0; i <= len(s)-len(sub); i++ {
if s[i:i+len(sub)] == sub {
return true
}
}
return false
}
// Logf 写入一条格式化日志到缓冲区
func Logf(format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)
LogBuf.Write([]byte(msg + "\n"))
}

60
server/utils/snowflake.go Normal file
View File

@@ -0,0 +1,60 @@
package utils
import (
"sync"
"time"
)
// Snowflake 雪花ID生成器
// 64位布局: 41位时间戳 + 10位机器ID + 12位序列号
// 生成约19位数字, 前端用字符串表示避免精度丢失
type Snowflake struct {
mu sync.Mutex
epoch int64 // 自定义纪元(毫秒)
machineID int64 // 机器ID (0-1023)
sequence int64 // 序列号 (0-4095)
lastTime int64 // 上次生成ID的时间戳
}
var sf *Snowflake
func init() {
sf = NewSnowflake(1704067200000, 1) // 2024-01-01 00:00:00 UTC 作为纪元
}
func NewSnowflake(epoch int64, machineID int64) *Snowflake {
return &Snowflake{
epoch: epoch,
machineID: machineID & 0x3FF, // 10位, 最大1023
}
}
// NextID 生成下一个唯一ID
func (s *Snowflake) NextID() uint64 {
s.mu.Lock()
defer s.mu.Unlock()
now := time.Now().UnixMilli() - s.epoch
if now == s.lastTime {
s.sequence = (s.sequence + 1) & 0xFFF // 12位, 最大4095
if s.sequence == 0 {
// 序列号溢出, 等待下一毫秒
for now <= s.lastTime {
now = time.Now().UnixMilli() - s.epoch
}
}
} else {
s.sequence = 0
}
s.lastTime = now
// 组装ID: 时间戳左移22位 + 机器ID左移12位 + 序列号
return uint64(now)<<22 | uint64(s.machineID)<<12 | uint64(s.sequence)
}
// GenID 全局便捷方法
func GenID() uint64 {
return sf.NextID()
}