chore: init bj_power monorepo (dashboard/mes/wms/wms_client/workstation), clear subproject git metadata and align naming to folder names

This commit is contained in:
SunYF
2026-08-27 10:09:54 +08:00
commit 1f0ee844a4
408 changed files with 102201 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
package auth
import "golang.org/x/crypto/bcrypt"
const bcryptCost = 10
func HashPassword(plain string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(plain), bcryptCost)
if err != nil {
return "", err
}
return string(bytes), nil
}
func CheckPassword(plain, hashed string) bool {
return bcrypt.CompareHashAndPassword([]byte(hashed), []byte(plain)) == nil
}
+116
View File
@@ -0,0 +1,116 @@
package auth
import (
"context"
"errors"
"log/slog"
"sync"
"time"
)
// TokenStore 刷新令牌存储接口
type TokenStore interface {
// Setex 存储 refresh token,过期时间 seconds
Setex(ctx context.Context, key string, value string, seconds int) error
// Get 获取 refresh token
Get(ctx context.Context, key string) (string, error)
// Del 删除 refresh token(退出登录)
Del(ctx context.Context, key string) error
}
// ErrNotFound 表示 key 不存在
var ErrNotFound = errors.New("token not found")
// InMemoryTokenStore 内存存储刷新令牌,用于单机测试
// 不需要 Redis 依赖
type InMemoryTokenStore struct {
mu sync.RWMutex
data map[string]tokenEntry
stop chan struct{}
timer *time.Ticker
}
type tokenEntry struct {
value string
expires time.Time
}
// NewInMemoryTokenStore 创建内存令牌存储
// 每 60 秒自动清理过期项
func NewInMemoryTokenStore() *InMemoryTokenStore {
store := &InMemoryTokenStore{
data: make(map[string]tokenEntry),
stop: make(chan struct{}),
}
store.timer = time.NewTicker(60 * time.Second)
go store.cleanupLoop()
return store
}
func (s *InMemoryTokenStore) Setex(_ context.Context, key string, value string, seconds int) error {
s.mu.Lock()
defer s.mu.Unlock()
s.data[key] = tokenEntry{
value: value,
expires: time.Now().Add(time.Duration(seconds) * time.Second),
}
return nil
}
func (s *InMemoryTokenStore) Del(_ context.Context, key string) error {
s.mu.Lock()
defer s.mu.Unlock()
delete(s.data, key)
return nil
}
func (s *InMemoryTokenStore) Get(_ context.Context, key string) (string, error) {
s.mu.RLock()
defer s.mu.RUnlock()
entry, ok := s.data[key]
if !ok {
return "", ErrNotFound
}
if time.Now().After(entry.expires) {
delete(s.data, key)
return "", ErrNotFound
}
return entry.value, nil
}
func (s *InMemoryTokenStore) cleanupLoop() {
for {
select {
case <-s.timer.C:
func() {
defer func() {
if r := recover(); r != nil {
slog.Error("token存储: 清理panic恢复", "panic", r)
}
}()
s.cleanup()
}()
case <-s.stop:
s.timer.Stop()
return
}
}
}
func (s *InMemoryTokenStore) cleanup() {
s.mu.Lock()
defer s.mu.Unlock()
now := time.Now()
for k, v := range s.data {
if now.After(v.expires) {
delete(s.data, k)
}
}
}
func (s *InMemoryTokenStore) Stop() {
close(s.stop)
}