Files
EasyGoAdmin_GoFrame_EleVue/internal/consts/context_key.go
T
2026-10-20 11:37:25 +08:00

248 lines
7.3 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 consts
import (
"context"
"time"
"github.com/gogf/gf/v2/frame/g"
)
// ============================== 请求上下文键与读写工具 ==============================
// contextKey 上下文键私有类型
// 使用私有类型避免跨包键名冲突
type contextKey string
// 请求上下文键
// 由 JWT、租户中间件写入,供全链路读取
const (
KeyUserID contextKey = "userID" // 当前登录用户ID
KeyTenantID contextKey = "tenantID" // 当前租户ID(0=平台级)
KeyUsername contextKey = "username" // 当前登录用户名
KeyRealname contextKey = "realname" // 当前登录用户姓名
KeyRoles contextKey = "roles" // 角色编码集合 []string
KeyPerms contextKey = "perms" // 权限节点集合 []string,如 sys:user:page
KeyTokenJTI contextKey = "tokenJTI" // 当前令牌 jti
KeyTokenExp contextKey = "tokenExpire" // 令牌过期时间 time.Time,用于登出黑名单TTL
KeyDataScope contextKey = "dataScope" // 角色数据范围(多角色取最宽松),见 DataScopeXxx 常量
KeyDeptID contextKey = "deptID" // 当前登录用户部门ID(0=未分配)
// 请求元信息,由 Response 中间件写入,供登录日志、操作日志读取
KeyClientIP contextKey = "clientIP" // 客户端IP
KeyUserAgent contextKey = "userAgent" // User-Agent
KeyReqMethod contextKey = "reqMethod" // HTTP方法
KeyReqURL contextKey = "reqURL" // 请求URL
)
// WithUserID 写入当前登录用户ID
func WithUserID(ctx context.Context, id int) context.Context {
return context.WithValue(ctx, KeyUserID, id)
}
// GetUserID 读取当前登录用户ID
// 未登录时返回 0
func GetUserID(ctx context.Context) int {
v, _ := ctx.Value(KeyUserID).(int)
return v
}
// WithTenantID 写入当前租户ID
// 0 表示平台级
func WithTenantID(ctx context.Context, id int) context.Context {
return context.WithValue(ctx, KeyTenantID, id)
}
// CtxTenantID 读取上下文原始租户ID
//
// 未登录时返回 0(平台级)。仅供租户隔离设施使用(超管判断、查询过滤、中间件校验),
// 业务模块取归属租户请使用 GetTenantID。
func CtxTenantID(ctx context.Context) int {
v, _ := ctx.Value(KeyTenantID).(int)
return v
}
// DefaultTenantID 默认归属租户ID
//
// 超管新增租户级数据时使用。读取配置 tenant.defaultId,未配置或非法值(≤0)回退 1。
func DefaultTenantID(ctx context.Context) int {
v := g.Cfg().MustGet(ctx, "tenant.defaultId").Int()
if v <= 0 {
return 1
}
return v
}
// GetTenantID 读取当前上下文的归属租户ID
//
// 租户用户返回自身租户ID,超管返回默认租户ID。
// 业务模块新增、导入、唯一校验等取归属租户统一使用本方法。
func GetTenantID(ctx context.Context) int {
if t := CtxTenantID(ctx); t > 0 {
return t
}
return DefaultTenantID(ctx)
}
// IsPlatform 是否平台级租户
// 上下文租户ID为0时表示平台级(超管)
func IsPlatform(ctx context.Context) bool {
return CtxTenantID(ctx) == 0
}
// WithUsername 写入当前登录用户名
func WithUsername(ctx context.Context, username string) context.Context {
return context.WithValue(ctx, KeyUsername, username)
}
// GetUsername 读取当前登录用户名
func GetUsername(ctx context.Context) string {
v, _ := ctx.Value(KeyUsername).(string)
return v
}
// WithRealname 写入当前登录用户姓名
func WithRealname(ctx context.Context, realname string) context.Context {
return context.WithValue(ctx, KeyRealname, realname)
}
// GetRealname 读取当前登录用户姓名
// 审计字段 create_user 优先使用本方法
func GetRealname(ctx context.Context) string {
v, _ := ctx.Value(KeyRealname).(string)
return v
}
// WithRoles 写入当前用户角色编码
func WithRoles(ctx context.Context, roles []string) context.Context {
return context.WithValue(ctx, KeyRoles, roles)
}
// GetRoles 读取当前用户角色编码
func GetRoles(ctx context.Context) []string {
v, _ := ctx.Value(KeyRoles).([]string)
return v
}
// WithPerms 写入当前用户权限节点
func WithPerms(ctx context.Context, perms []string) context.Context {
return context.WithValue(ctx, KeyPerms, perms)
}
// GetPerms 读取当前用户权限节点
func GetPerms(ctx context.Context) []string {
v, _ := ctx.Value(KeyPerms).([]string)
return v
}
// HasPerm 校验权限节点
// 权限节点为空视为无需校验;超级管理员拥有全部权限
func HasPerm(ctx context.Context, permission string) bool {
if permission == "" {
return true
}
for _, r := range GetRoles(ctx) {
if r == RoleCodeSuperAdmin {
return true
}
}
for _, p := range GetPerms(ctx) {
if p == permission {
return true
}
}
return false
}
// 数据范围档位(角色 data_scope 列值;数值越小可见面越宽)
const (
DataScopeAll = 1 // 全部(租户隔离之内)
DataScopeDeptAndBelow = 2 // 本部门及以下
DataScopeDept = 3 // 本部门
DataScopeSelf = 4 // 仅本人
)
// WithDataScope 写入当前用户数据范围
func WithDataScope(ctx context.Context, scope int) context.Context {
return context.WithValue(ctx, KeyDataScope, scope)
}
// GetDataScope 读取当前用户数据范围
// 未注入时返回 DataScopeAll(视为全量可见)
func GetDataScope(ctx context.Context) int {
v, _ := ctx.Value(KeyDataScope).(int)
if v <= 0 {
return DataScopeAll
}
return v
}
// WithDeptID 写入当前登录用户部门ID
func WithDeptID(ctx context.Context, id int) context.Context {
return context.WithValue(ctx, KeyDeptID, id)
}
// GetDeptID 读取当前登录用户部门ID
// 未分配或未登录时返回 0
func GetDeptID(ctx context.Context) int {
v, _ := ctx.Value(KeyDeptID).(int)
return v
}
// WithTokenJTI 写入当前令牌 jti
// 登出时依据该值将令牌加入黑名单
func WithTokenJTI(ctx context.Context, jti string) context.Context {
return context.WithValue(ctx, KeyTokenJTI, jti)
}
// GetTokenJTI 读取当前令牌 jti
func GetTokenJTI(ctx context.Context) string {
v, _ := ctx.Value(KeyTokenJTI).(string)
return v
}
// WithTokenExpire 写入当前令牌过期时间
// 黑名单 TTL 取令牌剩余有效期
func WithTokenExpire(ctx context.Context, t time.Time) context.Context {
return context.WithValue(ctx, KeyTokenExp, t)
}
// GetTokenExpire 读取当前令牌过期时间
func GetTokenExpire(ctx context.Context) time.Time {
v, _ := ctx.Value(KeyTokenExp).(time.Time)
return v
}
// WithRequestMeta 写入请求元信息
// 由 Response 中间件调用
func WithRequestMeta(ctx context.Context, ip, userAgent, method, url string) context.Context {
ctx = context.WithValue(ctx, KeyClientIP, ip)
ctx = context.WithValue(ctx, KeyUserAgent, userAgent)
ctx = context.WithValue(ctx, KeyReqMethod, method)
ctx = context.WithValue(ctx, KeyReqURL, url)
return ctx
}
// GetClientIP 读取客户端IP
func GetClientIP(ctx context.Context) string {
v, _ := ctx.Value(KeyClientIP).(string)
return v
}
// GetUserAgent 读取 User-Agent
func GetUserAgent(ctx context.Context) string {
v, _ := ctx.Value(KeyUserAgent).(string)
return v
}
// GetReqMethod 读取HTTP方法
func GetReqMethod(ctx context.Context) string {
v, _ := ctx.Value(KeyReqMethod).(string)
return v
}
// GetReqURL 读取请求URL
func GetReqURL(ctx context.Context) string {
v, _ := ctx.Value(KeyReqURL).(string)
return v
}