签入脚本

This commit is contained in:
小蚂蚁云
2026-10-20 11:37:25 +08:00
commit 7f5e8470af
909 changed files with 4045080 additions and 0 deletions
+88
View File
@@ -0,0 +1,88 @@
package logic
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"easygoadmin/internal/consts"
"easygoadmin/internal/dao"
)
// ============================== 角色数据权限(行级过滤) ==============================
//
// 档位(role.data_scope,多角色在身份加载层取最宽松):
// 1-全部 租户隔离之内不过滤
// 2-本部门及以下 dept_id IN (自身部门 + 全部子孙部门)
// 3-本部门 dept_id = 自身部门
// 4-仅本人 id = 自身用户ID
//
// 生效范围:挂接本函数的模块其 Page/List/导出(applyFilters 链)自动生效;
// Detail/Update/Delete 不过滤,由 permission 节点与租户隔离兜底。
// 租户隔离、软删过滤由 dao.Ctx(hooks.ApplyCtx)先于本链注入,两层独立叠加。
// ApplyDataScope 数据权限过滤工厂
//
// 返回可挂到 ModuleSpec.DataScope 的过滤函数;deptColumn 为行上的部门列名,
// 无部门归属的行表(如内容模块)后续可按需提供按创建人过滤的变体。
func ApplyDataScope(deptColumn string) DataScopeFunc {
return func(ctx context.Context, m *gdb.Model, req any) *gdb.Model {
if dataScopeBypass(ctx) {
return m
}
scope := consts.GetDataScope(ctx)
if scope <= consts.DataScopeAll {
return m
}
uid := consts.GetUserID(ctx)
deptId := consts.GetDeptID(ctx)
switch {
case scope >= consts.DataScopeSelf || deptId <= 0:
// 仅本人;未分配部门的用户挂部门档时降级为仅本人(安全兜底)
return m.Where("id", uid)
case scope == consts.DataScopeDept:
return m.Where(deptColumn, deptId)
case scope == consts.DataScopeDeptAndBelow:
return m.WhereIn(deptColumn, deptSubtreeIds(ctx, deptId))
}
return m
}
}
// dataScopeBypass 数据范围豁免判断
// 平台级(超管)或持有超管角色编码时全量可见,与权限通配逻辑对齐
func dataScopeBypass(ctx context.Context) bool {
if consts.IsPlatform(ctx) {
return true
}
for _, r := range consts.GetRoles(ctx) {
if r == consts.RoleCodeSuperAdmin {
return true
}
}
return false
}
// deptSubtreeIds 收集部门自身及全部子孙部门ID
//
// 部门为 parent_id 树且体量小,直接全量拉取后 BFS;
// 查询经 dao.Ctx(租户隔离+软删),后续如成热点可加短时缓存
func deptSubtreeIds(ctx context.Context, deptId int) []int {
rows, err := dao.Dept.Ctx(ctx).Fields("id, parent_id").All()
if err != nil || len(rows) == 0 {
return []int{deptId}
}
children := make(map[int][]int, len(rows))
for _, r := range rows {
pid := r["parent_id"].Int()
children[pid] = append(children[pid], r["id"].Int())
}
ids := []int{deptId}
for queue := []int{deptId}; len(queue) > 0; queue = queue[1:] {
for _, cid := range children[queue[0]] {
ids = append(ids, cid)
queue = append(queue, cid)
}
}
return ids
}