hyapp-server/pkg/appcode/appcode.go
2026-05-02 13:02:38 +08:00

65 lines
1.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package appcode 集中处理多 App 租户键的归一化和 context 透传。
package appcode
import (
"context"
"crypto/rand"
"fmt"
"strings"
)
const (
// Default 是当前开发阶段的种子 App旧请求未显式携带 app_code 时统一落到 lalu。
Default = "lalu"
)
type contextKey struct{}
// Normalize 把外部输入收敛成数据库使用的短 app_code。
func Normalize(value string) string {
value = strings.ToLower(strings.TrimSpace(value))
if value == "" {
// 开发阶段不保留历史兼容表结构,但测试和后台任务仍需要一个稳定默认租户。
return Default
}
return value
}
// WithContext 把 app_code 写入 context供 service/repository 在不扩散方法签名的情况下取用。
func WithContext(ctx context.Context, value string) context.Context {
return context.WithValue(ctx, contextKey{}, Normalize(value))
}
// FromContext 从 context 读取 app_code缺失时返回当前开发默认 App。
func FromContext(ctx context.Context) string {
if ctx == nil {
return Default
}
value, _ := ctx.Value(contextKey{}).(string)
return Normalize(value)
}
// NewScopedID 生成对客户端暴露的 App 长 ID。
// 格式固定为 app_code + "_" + uuid保证同一个 ID 可直接作为用户长 ID、房间 ID 和腾讯 IM/RTC 字符串标识。
func NewScopedID(value string) string {
app := Normalize(value)
var bytes [16]byte
if _, err := rand.Read(bytes[:]); err != nil {
// crypto/rand 失败极少见;这里退化为全 0 仍保留格式,后续数据库唯一键会兜底冲突。
return fmt.Sprintf("%s_00000000-0000-4000-8000-000000000000", app)
}
bytes[6] = (bytes[6] & 0x0f) | 0x40
bytes[8] = (bytes[8] & 0x3f) | 0x80
return fmt.Sprintf("%s_%08x-%04x-%04x-%04x-%012x",
app,
bytes[0:4],
bytes[4:6],
bytes[6:8],
bytes[8:10],
bytes[10:16],
)
}