1、泛型化参数,预留泛型约束,方便以后代码扩展的类型安全校验

2、升级goframe至v2.7.3
This commit is contained in:
apefuu
2024-09-19 19:33:00 +08:00
parent 2a87055b62
commit f18ce6384b
57 changed files with 221 additions and 220 deletions

View File

@@ -14,25 +14,25 @@ import (
)
// Init 初始化上下文对象指针到上下文对象中,以便后续的请求流程中可以修改
func Init(r *ghttp.Request, customCtx *model.Context) {
func Init[T any](r *ghttp.Request, customCtx *model.Context[T]) {
r.SetCtxVar(consts.ContextHTTPKey, customCtx)
}
// Get 获得上下文变量如果没有设置那么返回nil
func Get(ctx context.Context) *model.Context {
func Get[T any](ctx context.Context) *model.Context[T] {
value := ctx.Value(consts.ContextHTTPKey)
if value == nil {
return nil
}
if localCtx, ok := value.(*model.Context); ok {
if localCtx, ok := value.(*model.Context[T]); ok {
return localCtx
}
return nil
}
// SetUser 将上下文信息设置到上下文请求中,注意是完整覆盖
func SetUser(ctx context.Context, user *model.Identity) {
c := Get(ctx)
func SetUser[T any](ctx context.Context, user *model.Identity) {
c := Get[T](ctx)
if c == nil {
g.Log().Warning(ctx, "contexts.SetUser, c == nil ")
return
@@ -41,8 +41,8 @@ func SetUser(ctx context.Context, user *model.Identity) {
}
// SetResponse 设置组件响应 用于访问日志使用
func SetResponse(ctx context.Context, response *model.Response) {
c := Get(ctx)
func SetResponse[T any](ctx context.Context, response *model.Response[T]) {
c := Get[T](ctx)
if c == nil {
g.Log().Warning(ctx, "contexts.SetResponse, c == nil ")
return
@@ -51,8 +51,8 @@ func SetResponse(ctx context.Context, response *model.Response) {
}
// SetModule 设置应用模块
func SetModule(ctx context.Context, module string) {
c := Get(ctx)
func SetModule[T any](ctx context.Context, module string) {
c := Get[T](ctx)
if c == nil {
g.Log().Warning(ctx, "contexts.SetModule, c == nil ")
return
@@ -61,8 +61,8 @@ func SetModule(ctx context.Context, module string) {
}
// GetUser 获取用户信息
func GetUser(ctx context.Context) *model.Identity {
c := Get(ctx)
func GetUser[T any](ctx context.Context) *model.Identity {
c := Get[T](ctx)
if c == nil {
return nil
}
@@ -70,8 +70,8 @@ func GetUser(ctx context.Context) *model.Identity {
}
// GetUserId 获取用户ID
func GetUserId(ctx context.Context) int64 {
user := GetUser(ctx)
func GetUserId[T any](ctx context.Context) int64 {
user := GetUser[T](ctx)
if user == nil {
return 0
}
@@ -79,8 +79,8 @@ func GetUserId(ctx context.Context) int64 {
}
// GetRoleId 获取用户角色ID
func GetRoleId(ctx context.Context) int64 {
user := GetUser(ctx)
func GetRoleId[T any](ctx context.Context) int64 {
user := GetUser[T](ctx)
if user == nil {
return 0
}
@@ -88,8 +88,8 @@ func GetRoleId(ctx context.Context) int64 {
}
// GetRoleKey 获取用户角色唯一编码
func GetRoleKey(ctx context.Context) string {
user := GetUser(ctx)
func GetRoleKey[T any](ctx context.Context) string {
user := GetUser[T](ctx)
if user == nil {
return ""
}
@@ -97,8 +97,8 @@ func GetRoleKey(ctx context.Context) string {
}
// GetDeptType 获取用户部门类型
func GetDeptType(ctx context.Context) string {
user := GetUser(ctx)
func GetDeptType[T any](ctx context.Context) string {
user := GetUser[T](ctx)
if user == nil {
return ""
}
@@ -106,28 +106,28 @@ func GetDeptType(ctx context.Context) string {
}
// IsCompanyDept 是否为公司部门
func IsCompanyDept(ctx context.Context) bool {
return GetDeptType(ctx) == consts.DeptTypeCompany
func IsCompanyDept[T any](ctx context.Context) bool {
return GetDeptType[T](ctx) == consts.DeptTypeCompany
}
// IsTenantDept 是否为租户部门
func IsTenantDept(ctx context.Context) bool {
return GetDeptType(ctx) == consts.DeptTypeTenant
func IsTenantDept[T any](ctx context.Context) bool {
return GetDeptType[T](ctx) == consts.DeptTypeTenant
}
// IsMerchantDept 是否为商户部门
func IsMerchantDept(ctx context.Context) bool {
return GetDeptType(ctx) == consts.DeptTypeMerchant
func IsMerchantDept[T any](ctx context.Context) bool {
return GetDeptType[T](ctx) == consts.DeptTypeMerchant
}
// IsUserDept 是否为普通用户部门
func IsUserDept(ctx context.Context) bool {
return GetDeptType(ctx) == consts.DeptTypeUser
func IsUserDept[T any](ctx context.Context) bool {
return GetDeptType[T](ctx) == consts.DeptTypeUser
}
// GetModule 获取应用模块
func GetModule(ctx context.Context) string {
c := Get(ctx)
func GetModule[T any](ctx context.Context) string {
c := Get[T](ctx)
if c == nil {
return ""
}
@@ -135,59 +135,59 @@ func GetModule(ctx context.Context) string {
}
// SetAddonName 设置插件信息
func SetAddonName(ctx context.Context, name string) {
c := Get(ctx)
func SetAddonName[T any](ctx context.Context, name string) {
c := Get[T](ctx)
if c == nil {
g.Log().Warning(ctx, "contexts.SetAddonName, c == nil ")
return
}
Get(ctx).AddonName = name
Get[T](ctx).AddonName = name
}
// IsAddonRequest 是否为插件模块请求
func IsAddonRequest(ctx context.Context) bool {
c := Get(ctx)
func IsAddonRequest[T any](ctx context.Context) bool {
c := Get[T](ctx)
if c == nil {
return false
}
return GetAddonName(ctx) != ""
return GetAddonName[T](ctx) != ""
}
// GetAddonName 获取插件信息
func GetAddonName(ctx context.Context) string {
c := Get(ctx)
func GetAddonName[T any](ctx context.Context) string {
c := Get[T](ctx)
if c == nil {
return ""
}
return Get(ctx).AddonName
return Get[T](ctx).AddonName
}
// SetData 设置额外数据
func SetData(ctx context.Context, k string, v interface{}) {
c := Get(ctx)
func SetData[T any](ctx context.Context, k string, v interface{}) {
c := Get[T](ctx)
if c == nil {
g.Log().Warning(ctx, "contexts.SetData, c == nil ")
return
}
Get(ctx).Data[k] = v
Get[T](ctx).Data[k] = v
}
// SetDataMap 设置额外数据
func SetDataMap(ctx context.Context, vs g.Map) {
c := Get(ctx)
func SetDataMap[T any](ctx context.Context, vs g.Map) {
c := Get[T](ctx)
if c == nil {
g.Log().Warning(ctx, "contexts.SetData, c == nil ")
return
}
for k, v := range vs {
Get(ctx).Data[k] = v
Get[T](ctx).Data[k] = v
}
}
// GetData 获取额外数据
func GetData(ctx context.Context) g.Map {
c := Get(ctx)
func GetData[T any](ctx context.Context) g.Map {
c := Get[T](ctx)
if c == nil {
return nil
}

View File

@@ -19,7 +19,7 @@ import (
// FilterAuth 过滤数据权限
// 通过上下文中的用户角色权限和表中是否含有需要过滤的字段附加查询条件
func FilterAuth(m *gdb.Model) *gdb.Model {
func FilterAuth[T any](m *gdb.Model) *gdb.Model {
var (
needAuth bool
filterField string
@@ -40,16 +40,16 @@ func FilterAuth(m *gdb.Model) *gdb.Model {
if !needAuth {
return m
}
return m.Handler(FilterAuthWithField(filterField))
return m.Handler(FilterAuthWithField[T](filterField))
}
// FilterAuthWithField 过滤数据权限,设置指定字段
func FilterAuthWithField(filterField string) func(m *gdb.Model) *gdb.Model {
func FilterAuthWithField[T any](filterField string) func(m *gdb.Model) *gdb.Model {
return func(m *gdb.Model) *gdb.Model {
var (
role *entity.AdminRole
ctx = m.GetCtx()
co = contexts.Get(ctx)
co = contexts.Get[T](ctx)
)
if co == nil || co.User == nil {

View File

@@ -30,13 +30,13 @@ func Model(m *gdb.Model, opt ...*Option) *gdb.Model {
option = DefaultOption
}
if option.FilterAuth {
m = m.Handler(FilterAuth)
m = m.Handler(FilterAuth[any])
}
if option.ForceCache {
m = m.Handler(ForceCache)
}
if option.FilterTenant {
m = m.Handler(FilterTenant)
m = m.Handler(FilterTenant[any])
}
return m
}

View File

@@ -14,7 +14,7 @@ import (
// FilterTenant 过滤多租户数据权限
// 根据部门类型识别当前租户、商户、用户身份,过滤只属于自己的数据
func FilterTenant(m *gdb.Model) *gdb.Model {
func FilterTenant[T any](m *gdb.Model) *gdb.Model {
var (
needAuth bool
filterField string
@@ -23,19 +23,19 @@ func FilterTenant(m *gdb.Model) *gdb.Model {
)
// 租户
if contexts.IsTenantDept(ctx) && gstr.InArray(fields, "tenant_id") {
if contexts.IsTenantDept[T](ctx) && gstr.InArray(fields, "tenant_id") {
needAuth = true
filterField = "tenant_id"
}
// 商户
if contexts.IsMerchantDept(ctx) && gstr.InArray(fields, "merchant_id") {
if contexts.IsMerchantDept[T](ctx) && gstr.InArray(fields, "merchant_id") {
needAuth = true
filterField = "merchant_id"
}
// 用户
if contexts.IsUserDept(ctx) && gstr.InArray(fields, "user_id") {
if contexts.IsUserDept[T](ctx) && gstr.InArray(fields, "user_id") {
needAuth = true
filterField = "user_id"
}
@@ -44,6 +44,6 @@ func FilterTenant(m *gdb.Model) *gdb.Model {
return m
}
m = m.Where(filterField, contexts.GetUserId(ctx))
m = m.Where(filterField, contexts.GetUserId[T](ctx))
return m
}

View File

@@ -165,7 +165,7 @@ func (h *hookSaveTenant) checkRelationSingle(idx any, relation, limitType string
return
}
relationId := contexts.GetUserId(h.ctx)
relationId := contexts.GetUserId[any](h.ctx)
switch relation {
case consts.DeptTypeTenant:
if ok = tr.TenantId == relationId; !ok {
@@ -210,8 +210,8 @@ func (h *hookSaveTenant) handle() (result sql.Result, err error) {
var (
update = make(g.Map)
fields = h.getFields()
memberId = contexts.GetUserId(h.ctx)
deptType = contexts.GetDeptType(h.ctx)
memberId = contexts.GetUserId[any](h.ctx)
deptType = contexts.GetDeptType[any](h.ctx)
tr *hgorm.TenantRelation
)
@@ -221,7 +221,7 @@ func (h *hookSaveTenant) handle() (result sql.Result, err error) {
}
// 非公司类型,加载自己的租户关系,用于重写关系
if !contexts.IsCompanyDept(h.ctx) {
if !contexts.IsCompanyDept[any](h.ctx) {
tr, err = h.getRelation(memberId)
if err != nil {
return nil, err

View File

@@ -22,12 +22,13 @@ func JsonExit(r *ghttp.Request, code int, message string, data ...interface{}) {
}
// RXml xml
func RXml(r *ghttp.Request, code int, message string, data ...interface{}) {
responseData := interface{}(nil)
func RXml[T any](r *ghttp.Request, code int, message string, data ...T) {
//responseData := interface{}(nil)
var responseData T
if len(data) > 0 {
responseData = data[0]
}
res := &model.Response{
res := &model.Response[T]{
Code: code,
Message: message,
Timestamp: gtime.Timestamp(),
@@ -52,12 +53,13 @@ func RXml(r *ghttp.Request, code int, message string, data ...interface{}) {
}
// RJson 标准返回结果数据结构封装
func RJson(r *ghttp.Request, code int, message string, data ...interface{}) {
responseData := interface{}(nil)
func RJson[T any](r *ghttp.Request, code int, message string, data ...T) {
//responseData := interface{}(nil)
var responseData T
if len(data) > 0 {
responseData = data[0]
}
res := &model.Response{
res := &model.Response[T]{
Code: code,
Message: message,
Timestamp: gtime.Timestamp(),
@@ -82,7 +84,7 @@ func RJson(r *ghttp.Request, code int, message string, data ...interface{}) {
}
// CustomJson 自定义JSON
func CustomJson(r *ghttp.Request, content interface{}) {
func CustomJson[T any](r *ghttp.Request, content T) {
// 清空响应
r.Response.ClearBuffer()
@@ -90,7 +92,7 @@ func CustomJson(r *ghttp.Request, content interface{}) {
r.Response.WriteJson(content)
// 加入到上下文
contexts.SetResponse(r.Context(), &model.Response{
contexts.SetResponse(r.Context(), &model.Response[T]{
Code: 0,
Message: "",
Data: content,

View File

@@ -67,7 +67,7 @@ func New(name ...string) UploadDrive {
}
// DoUpload 上传入口
func DoUpload(ctx context.Context, typ string, file *ghttp.UploadFile) (result *entity.SysAttachment, err error) {
func DoUpload[T any](ctx context.Context, typ string, file *ghttp.UploadFile) (result *entity.SysAttachment, err error) {
if file == nil {
err = gerror.New("文件必须!")
return
@@ -88,7 +88,7 @@ func DoUpload(ctx context.Context, typ string, file *ghttp.UploadFile) (result *
}
// 相同存储相同身份才复用
if result != nil && result.Drive == config.Drive && result.MemberId == contexts.GetUserId(ctx) && result.AppId == contexts.GetModule(ctx) {
if result != nil && result.Drive == config.Drive && result.MemberId == contexts.GetUserId[T](ctx) && result.AppId == contexts.GetModule[T](ctx) {
return
}
@@ -98,7 +98,7 @@ func DoUpload(ctx context.Context, typ string, file *ghttp.UploadFile) (result *
return
}
// 写入附件记录
return write(ctx, meta, fullPath)
return write[T](ctx, meta, fullPath)
}
// ValidateFileMeta 验证文件元数据
@@ -215,11 +215,11 @@ func GenFullPath(basePath, ext string) string {
}
// write 写入附件记录
func write(ctx context.Context, meta *FileMeta, fullPath string) (models *entity.SysAttachment, err error) {
func write[T any](ctx context.Context, meta *FileMeta, fullPath string) (models *entity.SysAttachment, err error) {
models = &entity.SysAttachment{
Id: 0,
AppId: contexts.GetModule(ctx),
MemberId: contexts.GetUserId(ctx),
AppId: contexts.GetModule[T](ctx),
MemberId: contexts.GetUserId[T](ctx),
Drive: config.Drive,
Size: meta.Size,
Path: fullPath,
@@ -264,7 +264,7 @@ func HasFile(ctx context.Context, md5 string) (res *entity.SysAttachment, err er
}
// CheckMultipart 检查文件分片
func CheckMultipart(ctx context.Context, in *CheckMultipartParams) (res *CheckMultipartModel, err error) {
func CheckMultipart[T any](ctx context.Context, in *CheckMultipartParams) (res *CheckMultipartModel, err error) {
res = new(CheckMultipartModel)
meta := new(FileMeta)
@@ -295,7 +295,7 @@ func CheckMultipart(ctx context.Context, in *CheckMultipartParams) (res *CheckMu
}
// 文件已存在,直接返回。相同存储相同身份才复用
if result != nil && result.Drive == config.Drive && result.MemberId == contexts.GetUserId(ctx) && result.AppId == contexts.GetModule(ctx) {
if result != nil && result.Drive == config.Drive && result.MemberId == contexts.GetUserId[T](ctx) && result.AppId == contexts.GetModule[T](ctx) {
res.Attachment = result
return
}
@@ -305,7 +305,7 @@ func CheckMultipart(ctx context.Context, in *CheckMultipartParams) (res *CheckMu
}
in.meta = meta
progress, err := GetOrCreateMultipartProgress(ctx, in)
progress, err := GetOrCreateMultipartProgress[T](ctx, in)
if err != nil {
return nil, err
}
@@ -329,13 +329,13 @@ func CalcUploadProgress(uploadedIndex []int, shardCount int) float64 {
}
// GenUploadId 生成上传ID
func GenUploadId(ctx context.Context, md5 string) string {
return fmt.Sprintf("%v:%v:%v@%v", md5, contexts.GetUserId(ctx), contexts.GetModule(ctx), config.Drive)
func GenUploadId[T any](ctx context.Context, md5 string) string {
return fmt.Sprintf("%v:%v:%v@%v", md5, contexts.GetUserId[T](ctx), contexts.GetModule[T](ctx), config.Drive)
}
// GetOrCreateMultipartProgress 获取或创建分片上传事件进度
func GetOrCreateMultipartProgress(ctx context.Context, in *CheckMultipartParams) (res *MultipartProgress, err error) {
uploadId := GenUploadId(ctx, in.Md5)
func GetOrCreateMultipartProgress[T any](ctx context.Context, in *CheckMultipartParams) (res *MultipartProgress, err error) {
uploadId := GenUploadId[T](ctx, in.Md5)
res, err = GetMultipartProgress(ctx, uploadId)
if err != nil {
return nil, err

View File

@@ -55,7 +55,7 @@ func (d *LocalDrive) Upload(ctx context.Context, file *ghttp.UploadFile) (fullPa
// CreateMultipart 创建分片事件
func (d *LocalDrive) CreateMultipart(ctx context.Context, in *CheckMultipartParams) (mp *MultipartProgress, err error) {
mp = new(MultipartProgress)
mp.UploadId = GenUploadId(ctx, in.Md5)
mp.UploadId = GenUploadId[any](ctx, in.Md5)
mp.Meta = in.meta
mp.ShardCount = in.ShardCount
mp.UploadedIndex = make([]int, 0)
@@ -119,7 +119,7 @@ func (d *LocalDrive) UploadPart(ctx context.Context, in *UploadPartParams) (res
}
// 写入附件记录
attachment, err := write(ctx, in.mp.Meta, finalDirPath)
attachment, err := write[any](ctx, in.mp.Meta, finalDirPath)
if err != nil {
return nil, err
}

View File

@@ -90,7 +90,7 @@ func Login(ctx context.Context, user *model.Identity) (string, int64, error) {
}
// Logout 注销登录
func Logout(r *ghttp.Request) (err error) {
func Logout[T any](r *ghttp.Request) (err error) {
var (
ctx = r.Context()
header = GetAuthorization(r)
@@ -112,9 +112,9 @@ func Logout(r *ghttp.Request) (err error) {
// 认证key
authKey = GetAuthKey(header)
// 登录token
tokenKey = GetTokenKey(contexts.GetModule(ctx), authKey)
tokenKey = GetTokenKey(contexts.GetModule[T](ctx), authKey)
// 身份绑定
bindKey = GetBindKey(contexts.GetModule(ctx), claims.Id)
bindKey = GetBindKey(contexts.GetModule[T](ctx), claims.Id)
)
// 删除token