| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- package dept
- import (
- "context"
- "strings"
- "perms-system-server/internal/consts"
- "perms-system-server/internal/middleware"
- deptModel "perms-system-server/internal/model/dept"
- "perms-system-server/internal/response"
- "perms-system-server/internal/svc"
- "perms-system-server/internal/types"
- "github.com/zeromicro/go-zero/core/logx"
- )
- type DeptTreeLogic struct {
- logx.Logger
- ctx context.Context
- svcCtx *svc.ServiceContext
- }
- func NewDeptTreeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeptTreeLogic {
- return &DeptTreeLogic{
- Logger: logx.WithContext(ctx),
- ctx: ctx,
- svcCtx: svcCtx,
- }
- }
- // DeptTree 部门树。超管 / 产品 ADMIN 返回完整组织架构树;其他成员仅返回以其 DeptPath
- // 为根的子树,避免 MEMBER 级账号枚举全公司组织结构、定位 DEV 部门用于针对性特权获取
- // (见审计 M-2)。未归属部门或 DeptPath 为空的成员返回空树。
- func (l *DeptTreeLogic) DeptTree() (resp []*types.DeptItem, err error) {
- caller := middleware.GetUserDetails(l.ctx)
- if caller == nil {
- return nil, response.ErrUnauthorized("未登录")
- }
- list, err := l.svcCtx.SysDeptModel.FindAll(l.ctx)
- if err != nil {
- return nil, err
- }
- fullAccess := caller.IsSuperAdmin || caller.MemberType == consts.MemberTypeAdmin
- if !fullAccess {
- if caller.DeptPath == "" {
- return make([]*types.DeptItem, 0), nil
- }
- filtered := make([]*deptModel.SysDept, 0, len(list))
- for _, d := range list {
- if strings.HasPrefix(d.Path, caller.DeptPath) {
- filtered = append(filtered, d)
- }
- }
- list = filtered
- }
- items := make([]*types.DeptItem, 0, len(list))
- for _, d := range list {
- items = append(items, &types.DeptItem{
- Id: d.Id,
- ParentId: d.ParentId,
- Name: d.Name,
- Path: d.Path,
- Sort: d.Sort,
- DeptType: d.DeptType,
- Remark: d.Remark,
- Status: d.Status,
- CreateTime: d.CreateTime,
- Children: make([]*types.DeptItem, 0),
- })
- }
- itemMap := make(map[int64]*types.DeptItem)
- for _, item := range items {
- itemMap[item.Id] = item
- }
- roots := make([]*types.DeptItem, 0)
- for _, item := range items {
- // 非特权成员下只保留 caller 子树:原树的上级部门不出现在 items 中,item.ParentId
- // 找不到父节点时应当把当前节点当成局部根展示,而不是报错丢弃。
- if _, hasParent := itemMap[item.ParentId]; item.ParentId == 0 || !hasParent {
- if fullAccess && item.ParentId != 0 {
- l.Errorf("DeptTree: dept id=%d has parentId=%d which does not exist, treated as root", item.Id, item.ParentId)
- }
- roots = append(roots, item)
- } else {
- itemMap[item.ParentId].Children = append(itemMap[item.ParentId].Children, item)
- }
- }
- return roots, nil
- }
|