mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-11-11 03:33:53 +08:00
版本预发布
This commit is contained in:
@@ -19,15 +19,6 @@ import (
|
||||
"hotgo/utility/tree"
|
||||
)
|
||||
|
||||
// GenJoinOnRelation 生成关联表关联条件
|
||||
func GenJoinOnRelation(masterTable, masterField, joinTable, alias, onField string) []string {
|
||||
return []string{
|
||||
joinTable,
|
||||
alias,
|
||||
fmt.Sprintf("`%s`.`%s` = `%s`.`%s`", alias, onField, masterTable, masterField),
|
||||
}
|
||||
}
|
||||
|
||||
type daoInstance interface {
|
||||
Table() string
|
||||
Ctx(ctx context.Context) *gdb.Model
|
||||
@@ -40,6 +31,15 @@ type Join struct {
|
||||
fields map[string]*gdb.TableField // 表字段列表
|
||||
}
|
||||
|
||||
// GenJoinOnRelation 生成关联表关联条件
|
||||
func GenJoinOnRelation(masterTable, masterField, joinTable, alias, onField string) []string {
|
||||
return []string{
|
||||
joinTable,
|
||||
alias,
|
||||
fmt.Sprintf("`%s`.`%s` = `%s`.`%s`", alias, onField, masterTable, masterField),
|
||||
}
|
||||
}
|
||||
|
||||
// GenJoinSelect 生成关联表select
|
||||
// 这里会将实体中的字段驼峰转为下划线于数据库进行匹配,意味着数据库字段必须全部是小写字母+下划线的格式
|
||||
func GenJoinSelect(ctx context.Context, entity interface{}, masterDao interface{}, joins []*Join) (allFields string, err error) {
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
// Package hgorm
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package hgorm
|
||||
package handler
|
||||
|
||||
// 预处理
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
@@ -18,22 +10,15 @@ import (
|
||||
"hotgo/utility/tree"
|
||||
)
|
||||
|
||||
// HandlerFilterAuth 过滤数据权限
|
||||
// FilterAuth 过滤数据权限
|
||||
// 通过上下文中的用户角色权限和表中是否含有需要过滤的字段附加查询条件
|
||||
func HandlerFilterAuth(m *gdb.Model) *gdb.Model {
|
||||
func FilterAuth(m *gdb.Model) *gdb.Model {
|
||||
var (
|
||||
needAuth bool
|
||||
filterField string
|
||||
role *entity.AdminRole
|
||||
ctx = m.GetCtx()
|
||||
fields = escapeFieldsToSlice(m.GetFieldsStr())
|
||||
co = contexts.Get(ctx)
|
||||
)
|
||||
|
||||
if co == nil || co.User == nil {
|
||||
return m
|
||||
}
|
||||
|
||||
// 优先级:created_by > member_id
|
||||
if gstr.InArray(fields, "created_by") {
|
||||
needAuth = true
|
||||
@@ -49,43 +34,54 @@ func HandlerFilterAuth(m *gdb.Model) *gdb.Model {
|
||||
return m
|
||||
}
|
||||
|
||||
err := g.Model("admin_role").Where("id", co.User.RoleId).Scan(&role)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to role information err:%+v", err))
|
||||
}
|
||||
|
||||
if role == nil {
|
||||
panic("failed to role information roleModel == nil")
|
||||
}
|
||||
|
||||
sq := g.Model("admin_member").Fields("id")
|
||||
|
||||
switch role.DataScope {
|
||||
case consts.RoleDataAll: // 全部权限
|
||||
// ...
|
||||
case consts.RoleDataNowDept: // 当前部门
|
||||
m = m.WhereIn(filterField, sq.Where("dept_id", co.User.DeptId))
|
||||
case consts.RoleDataDeptAndSub: // 当前部门及以下部门
|
||||
m = m.WhereIn(filterField, sq.WhereIn("dept_id", GetDeptAndSub(co.User.DeptId)))
|
||||
case consts.RoleDataDeptCustom: // 自定义部门
|
||||
m = m.WhereIn(filterField, sq.WhereIn("dept_id", role.CustomDept.Var().Ints()))
|
||||
case consts.RoleDataSelf: // 仅自己
|
||||
m = m.Where(filterField, co.User.Id)
|
||||
case consts.RoleDataSelfAndSub: // 自己和直属下级
|
||||
m = m.WhereIn(filterField, GetSelfAndSub(co.User.Id))
|
||||
case consts.RoleDataSelfAndAllSub: // 自己和全部下级
|
||||
m = m.WhereIn(filterField, GetSelfAndAllSub(co.User.Id))
|
||||
|
||||
default:
|
||||
panic("dataScope is not registered")
|
||||
}
|
||||
|
||||
return m
|
||||
return m.Handler(FilterAuthWithField(filterField))
|
||||
}
|
||||
|
||||
// HandlerForceCache 强制缓存
|
||||
func HandlerForceCache(m *gdb.Model) *gdb.Model {
|
||||
return m.Cache(gdb.CacheOption{Duration: -1, Force: true})
|
||||
// FilterAuthWithField 过滤数据权限,设置指定字段
|
||||
func FilterAuthWithField(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)
|
||||
)
|
||||
|
||||
if co == nil || co.User == nil {
|
||||
return m
|
||||
}
|
||||
|
||||
err := g.Model("admin_role").Where("id", co.User.RoleId).Scan(&role)
|
||||
if err != nil {
|
||||
g.Log().Fatalf(ctx, "failed to role information err:%+v", err)
|
||||
}
|
||||
|
||||
if role == nil {
|
||||
g.Log().Fatalf(ctx, "failed to role information roleModel == nil")
|
||||
}
|
||||
|
||||
sq := g.Model("admin_member").Fields("id")
|
||||
|
||||
switch role.DataScope {
|
||||
case consts.RoleDataAll: // 全部权限
|
||||
// ...
|
||||
case consts.RoleDataNowDept: // 当前部门
|
||||
m = m.WhereIn(filterField, sq.Where("dept_id", co.User.DeptId))
|
||||
case consts.RoleDataDeptAndSub: // 当前部门及以下部门
|
||||
m = m.WhereIn(filterField, sq.WhereIn("dept_id", GetDeptAndSub(co.User.DeptId)))
|
||||
case consts.RoleDataDeptCustom: // 自定义部门
|
||||
m = m.WhereIn(filterField, sq.WhereIn("dept_id", role.CustomDept.Var().Ints()))
|
||||
case consts.RoleDataSelf: // 仅自己
|
||||
m = m.Where(filterField, co.User.Id)
|
||||
case consts.RoleDataSelfAndSub: // 自己和直属下级
|
||||
m = m.WhereIn(filterField, GetSelfAndSub(co.User.Id))
|
||||
case consts.RoleDataSelfAndAllSub: // 自己和全部下级
|
||||
m = m.WhereIn(filterField, GetSelfAndAllSub(co.User.Id))
|
||||
default:
|
||||
g.Log().Fatalf(ctx, "dataScope is not registered")
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
}
|
||||
|
||||
// escapeFieldsToSlice 将转义过的字段转换为字段集切片
|
||||
8
server/internal/library/hgorm/handler/force_cache.go
Normal file
8
server/internal/library/hgorm/handler/force_cache.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package handler
|
||||
|
||||
import "github.com/gogf/gf/v2/database/gdb"
|
||||
|
||||
// ForceCache 强制缓存
|
||||
func ForceCache(m *gdb.Model) *gdb.Model {
|
||||
return m.Cache(gdb.CacheOption{Duration: -1, Force: true})
|
||||
}
|
||||
39
server/internal/library/hgorm/handler/handler.go
Normal file
39
server/internal/library/hgorm/handler/handler.go
Normal file
@@ -0,0 +1,39 @@
|
||||
// Package handler
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package handler
|
||||
|
||||
// handler.
|
||||
import (
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
)
|
||||
|
||||
// Option 预处理选项
|
||||
type Option struct {
|
||||
FilterAuth bool // 过滤权限
|
||||
ForceCache bool // 强制缓存
|
||||
}
|
||||
|
||||
// DefaultOption 默认预处理选项
|
||||
var DefaultOption = &Option{
|
||||
FilterAuth: true,
|
||||
}
|
||||
|
||||
func Model(m *gdb.Model, opt ...*Option) *gdb.Model {
|
||||
var option *Option
|
||||
if len(opt) > 0 {
|
||||
option = opt[0]
|
||||
} else {
|
||||
option = DefaultOption
|
||||
}
|
||||
if option.FilterAuth {
|
||||
m = m.Handler(FilterAuth)
|
||||
}
|
||||
if option.ForceCache {
|
||||
m = m.Handler(ForceCache)
|
||||
}
|
||||
return m
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
// Package hgorm
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package hgorm
|
||||
|
||||
// 常用钩子
|
||||
3
server/internal/library/hgorm/hook/hook.go
Normal file
3
server/internal/library/hgorm/hook/hook.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package hook
|
||||
|
||||
// hook.
|
||||
58
server/internal/library/hgorm/hook/member.go
Normal file
58
server/internal/library/hgorm/hook/member.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package hook
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// MemberInfo 后台用户信息
|
||||
var MemberInfo = gdb.HookHandler{
|
||||
Select: func(ctx context.Context, in *gdb.HookSelectInput) (result gdb.Result, err error) {
|
||||
result, err = in.Next(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for i, record := range result {
|
||||
// 部门
|
||||
if !record["dept_id"].IsEmpty() {
|
||||
deptName, err := g.Model("admin_dept").Ctx(ctx).
|
||||
Fields("name").
|
||||
Where("id", record["dept_id"]).
|
||||
Value()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
record["deptName"] = deptName
|
||||
}
|
||||
|
||||
// 角色
|
||||
if !record["role_id"].IsEmpty() {
|
||||
roleName, err := g.Model("admin_role").Ctx(ctx).
|
||||
Fields("name").
|
||||
Where("id", record["role_id"]).
|
||||
Value()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
record["roleName"] = roleName
|
||||
}
|
||||
|
||||
if !record["password_hash"].IsEmpty() {
|
||||
record["password_hash"] = gvar.New("")
|
||||
}
|
||||
|
||||
if !record["salt"].IsEmpty() {
|
||||
record["salt"] = gvar.New("")
|
||||
}
|
||||
|
||||
if !record["auth_key"].IsEmpty() {
|
||||
record["auth_key"] = gvar.New("")
|
||||
}
|
||||
|
||||
result[i] = record
|
||||
}
|
||||
return
|
||||
},
|
||||
}
|
||||
59
server/internal/library/hgorm/hook/provinces.go
Normal file
59
server/internal/library/hgorm/hook/provinces.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package hook
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"hotgo/internal/library/location"
|
||||
)
|
||||
|
||||
// CityLabel 城市地区标签
|
||||
var CityLabel = gdb.HookHandler{
|
||||
Select: func(ctx context.Context, in *gdb.HookSelectInput) (result gdb.Result, err error) {
|
||||
result, err = in.Next(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
parse := func(id int64, index int) {
|
||||
cityLabel, err := location.ParseSimpleRegion(ctx, id)
|
||||
if err != nil {
|
||||
g.Log().Warningf(ctx, "hook.CityLabel parse err:%+v", err)
|
||||
}
|
||||
result[index]["cityLabel"] = gvar.New(cityLabel)
|
||||
return
|
||||
}
|
||||
|
||||
for i, record := range result {
|
||||
// 优先级: 区 > 市 > 省
|
||||
|
||||
cityId, ok := record["city_id"]
|
||||
if ok && !cityId.IsEmpty() {
|
||||
parse(cityId.Int64(), i)
|
||||
continue
|
||||
}
|
||||
|
||||
provinceId, ok := record["province_id"]
|
||||
if ok && !provinceId.IsEmpty() {
|
||||
parse(cityId.Int64(), i)
|
||||
continue
|
||||
}
|
||||
|
||||
// 以下是默认关联表 省市区字段
|
||||
|
||||
sysLogCityId, ok := record["sysLogCityId"]
|
||||
if ok && !sysLogCityId.IsEmpty() {
|
||||
parse(sysLogCityId.Int64(), i)
|
||||
continue
|
||||
}
|
||||
|
||||
sysLogProvinceId, ok := record["sysLogProvinceId"]
|
||||
if ok && !sysLogProvinceId.IsEmpty() {
|
||||
parse(cityId.Int64(), i)
|
||||
continue
|
||||
}
|
||||
}
|
||||
return
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user