Files
iotlcm/server/internal/logic/system/sys_dept.go
T
MiFaZhan 59eb34976a chore: 初始开源发布
iotlcm-admin-svr:管理后台服务。

- Go module:iotlcm → git.5iot.com/iotlcm-public/iotlcm-admin-svr(729 文件)
- 凭据与地址脱敏:JWT signingKey(含代码里的 MustGet 默认值)、
  MySQL DSN、Redis 口令、告警邮件发件人邮箱全部改为占位;
  私网 IP → 文档地址段;库名 xiujie_admin → iotlcm
- 真实手机号/邮箱 → 合法 11 位编造号 / example.com
- 移除内部资产:CI 触发器、过时 DDL(sql/db_iotlcm.sql)、
  私有依赖 go get 行、明文 registry 登录口令
- 启动 banner 统一 IOTLCM 方块字 + 社区惯例署名
- Dockerfile 改用公共基础镜像
- 拼错的 RADEME.md → README.md,README 重写
- 需要真实数据库的用例改为可用 IOTLCM_TEST_WITH_DB=1 显式启用
- 补 Apache-2.0 LICENSE,LF 行尾 + .gitattributes

数据库 schema 不随本仓发布(生产 DDL 已过时),README 已说明。
2026-10-23 14:48:30 +08:00

682 lines
21 KiB
Go

// package system
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package system
import (
"context"
"fmt"
"sort"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/consts"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/dao"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/contexts"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/event"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/xgorm/handler"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/do"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/request"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/service"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
)
type sSysDept struct {
}
func NewSysDept() *sSysDept {
return &sSysDept{}
}
func init() {
service.RegisterSysDept(NewSysDept())
}
func (l *sSysDept) Model(ctx context.Context, option ...*handler.Option) *gdb.Model {
if len(option) == 0 {
option = append(option, &handler.Option{
FilterTenant: true,
FilterAuth: true,
})
}
return handler.Model(dao.SysDept.Ctx(ctx), option...)
}
func (l *sSysDept) ModelQuery(ctx context.Context, option ...*handler.Option) *gdb.Model {
if len(option) == 0 {
option = append(option, &handler.Option{
FilterTenant: true,
FilterAuth: true,
})
}
return handler.Model(service.MemoryDB().DB(ctx).Ctx(ctx).Model(dao.SysDept.Table()), option...)
}
// GetDeptList 获取部门列表
func (l *sSysDept) GetDeptList(ctx context.Context, query model.SysDeptListParam) (items []*model.SysDeptListModel, total int, err error) {
m := l.ModelQuery(ctx)
if query.DeptName != "" {
m = m.WhereLike(dao.SysDept.Columns().DeptName, "%"+query.DeptName+"%")
}
if query.Status != "" {
m = m.Where(dao.SysDept.Columns().Status, query.Status)
}
if query.DeptType != nil {
m = m.Where(dao.SysDept.Columns().DeptType, *query.DeptType)
}
// 排序:按照显示顺序OrderNum从小到大排序,如果相同则按照部门ID从小到大排序
err = m.Page(1, 5000).Order(dao.SysDept.Columns().OrderNum, "ASC").Order(dao.SysDept.Columns().DeptId, "ASC").Scan(&items)
if err != nil {
return nil, 0, err
}
total = len(items)
return
}
// GetDeptById 获取部门详情
func (l *sSysDept) GetDeptById(ctx context.Context, id int64) (dept *model.SysDeptViewModel, err error) {
user := contexts.GetUser(ctx)
if user == nil {
return nil, gerror.NewCode(consts.CodeLoginExpired, "登录已过期")
}
mod := l.ModelQuery(ctx).Where(dao.SysDept.Columns().DeptId, id)
mod = mod.FieldsPrefix(dao.SysDept.Table(), model.SysDeptViewModel{})
err = mod.Scan(&dept)
if err != nil {
return nil, err
}
return dept, nil
}
// 构建树结构
func (l *sSysDept) DeptTree(ctx context.Context, parentDept *model.SysDeptTreeModel, deptList []*model.SysDeptListModel, ancestors string) (data []*model.SysDeptTreeModel, err error) {
data = make([]*model.SysDeptTreeModel, 0)
for _, dept := range deptList {
pId := int64(0)
if parentDept != nil {
pId = parentDept.DeptId
}
if dept.ParentId == pId {
item := &model.SysDeptTreeModel{
DeptId: dept.DeptId,
ParentId: dept.ParentId,
DeptName: dept.DeptName,
Key: fmt.Sprintf("%d", dept.DeptId),
Children: nil,
Ancestors: ancestors,
DeptType: dept.DeptType,
}
subDept, err := l.DeptTree(ctx, item, deptList, ancestors+","+fmt.Sprintf("%d", dept.DeptId))
if err != nil {
return nil, err
}
item.Children = subDept
data = append(data, item)
}
}
return
}
// GetDeptFullTree 组织管理页专用的完整部门树。
//
// 与 GetDeptTree 的区别:
// 1. 支持按组织名称模糊搜索、按状态/类型筛选(复用 GetDeptList 的过滤能力),
// 而 GetDeptTree 只支持 deptType 一个维度;
// 2. 节点携带 SysDeptListModel 的全部字段(含 deptCategory/status/createdAt),
// 供表格展示。
//
// 同样由后端一次建好嵌套 children 返回,前端无需再开 treeConfig.transform。
func (l *sSysDept) GetDeptFullTree(ctx context.Context, query model.SysDeptFullTreeParam) (items []*model.SysDeptFullTreeModel, err error) {
depts, _, err := l.GetDeptList(ctx, query.SysDeptListParam)
if err != nil {
return nil, err
}
// 带过滤条件时,命中的节点其父级可能被 WhereLike/Where 滤掉。
// 补齐这些祖先节点,使搜索结果仍呈现完整的层级链路(与前端
// filterDeptTree 的「命中节点保留整棵子树」语义一致),
// 否则用户看到的是一个parentId 悬空的孤立行,看不出它归属谁。
depts, err = l.withDeptAncestors(ctx, depts)
if err != nil {
return nil, err
}
return buildSysDeptFullTree(depts), nil
}
// withDeptAncestors 为列表中的每个节点补齐缺失的祖先,返回补齐后的完整列表。
//
// 输入通常是过滤后的结果集,节点可能缺失父级。做法是逐轮收集
// 「父级 id 不在当前集合中」的节点,按 id 批量补查,直到没有新节点补入为止。
// 补入的祖先沿用原有排序(order_num、dept_id),与 GetDeptList 一致。
func (l *sSysDept) withDeptAncestors(ctx context.Context, depts []*model.SysDeptListModel) ([]*model.SysDeptListModel, error) {
if len(depts) == 0 {
return depts, nil
}
present := make(map[int64]struct{}, len(depts))
for _, d := range depts {
if d != nil {
present[d.DeptId] = struct{}{}
}
}
merged := make([]*model.SysDeptListModel, 0, len(depts))
merged = append(merged, depts...)
// 每轮收集缺失父级 → 批量补查;轮数受部门层级深度约束(通常 2~3 轮)。
for {
missingIds := make([]int64, 0)
for _, d := range depts {
if d == nil || d.ParentId == 0 {
continue
}
if _, ok := present[d.ParentId]; !ok {
missingIds = append(missingIds, d.ParentId)
}
}
if len(missingIds) == 0 {
break
}
ancestors, err := l.GetDeptListByIds(ctx, missingIds)
if err != nil {
return nil, err
}
if len(ancestors) == 0 {
// 父级已不存在(脏数据或跨租户不可见),到此为止,避免死循环。
break
}
// 去重后并入;下一轮继续向上补。
fresh := make([]*model.SysDeptListModel, 0, len(ancestors))
for _, a := range ancestors {
if a == nil {
continue
}
if _, ok := present[a.DeptId]; ok {
continue
}
present[a.DeptId] = struct{}{}
fresh = append(fresh, a)
}
if len(fresh) == 0 {
break
}
merged = append(merged, fresh...)
depts = merged
}
// 补入的祖先是按「缺失父级 id 批次」查回来的,追加在尾部会打乱原有
// order_num / dept_id 排序,而 buildSysDeptFullTree 依赖入参顺序来保证
// 同层节点的展示次序,因此这里统一重排一次。
sort.SliceStable(merged, func(i, j int) bool {
if merged[i].OrderNum != merged[j].OrderNum {
return merged[i].OrderNum < merged[j].OrderNum
}
return merged[i].DeptId < merged[j].DeptId
})
return merged, nil
}
// buildSysDeptFullTree 把部门列表组装成嵌套树。
//
// 处理「可见根」:ParentId == 0 的顶层部门,以及 ParentId 指向本批次
// 中不存在的部门(例如按状态/名称过滤后父级被滤掉)—— 后者若丢弃会
// 导致整棵子树不可见,因此提升为根节点。逻辑与 buildSysMenuFullTree 一致。
func buildSysDeptFullTree(depts []*model.SysDeptListModel) []*model.SysDeptFullTreeModel {
if len(depts) == 0 {
return make([]*model.SysDeptFullTreeModel, 0)
}
// 保持入参顺序(查询已按 order_num、dept_id 排序),同时建立 id 索引。
nodes := make([]*model.SysDeptFullTreeModel, 0, len(depts))
nodeMaps := make(map[int64]*model.SysDeptFullTreeModel, len(depts))
for _, item := range depts {
if item == nil {
continue
}
node := &model.SysDeptFullTreeModel{
SysDeptListModel: *item,
Children: make([]*model.SysDeptFullTreeModel, 0),
}
nodes = append(nodes, node)
nodeMaps[item.DeptId] = node
}
roots := make([]*model.SysDeptFullTreeModel, 0, len(depts))
for _, node := range nodes {
if node.ParentId == 0 {
roots = append(roots, node)
continue
}
if parent, ok := nodeMaps[node.ParentId]; ok {
parent.Children = append(parent.Children, node)
continue
}
// 父级被过滤掉:提升为可见根,保证其子树仍可访问。
roots = append(roots, node)
}
return roots
}
// GetDeptTree 获取部门树
func (l *sSysDept) GetDeptTree(ctx context.Context, query model.SysDeptTreeParam) (items []*model.SysDeptTreeModel, err error) {
depts, _, err := l.GetDeptList(ctx, model.SysDeptListParam{})
if err != nil {
return nil, err
}
if len(depts) == 0 {
return make([]*model.SysDeptTreeModel, 0), nil
}
// 可见根:ParentId=0 或 ParentId 指向不在列表中的部门(孤立节点)
deptIdSet := make(map[int64]struct{}, len(depts))
for _, d := range depts {
deptIdSet[d.DeptId] = struct{}{}
}
rootDepts := make([]*model.SysDeptListModel, 0, len(depts))
for _, d := range depts {
if d.ParentId == 0 {
rootDepts = append(rootDepts, d)
continue
}
if _, ok := deptIdSet[d.ParentId]; !ok {
rootDepts = append(rootDepts, d)
}
}
items = make([]*model.SysDeptTreeModel, 0)
// 不带过滤:完整树
if query.DeptType == nil || *query.DeptType == "" {
for _, root := range rootDepts {
rootItem := l.deptTreeItem(root, fmt.Sprintf("%d", root.DeptId))
rootItem.Children, err = l.DeptTree(ctx, rootItem, depts, rootItem.Ancestors)
if err != nil {
return nil, err
}
items = append(items, rootItem)
}
return items, nil
}
// DeptType=0:根部门的直接子(按类型过滤)
if *query.DeptType == "0" {
for _, root := range rootDepts {
for _, dept := range depts {
if dept.ParentId == root.DeptId && dept.DeptType == 0 {
items = append(items, l.deptTreeItem(dept, fmt.Sprintf("%d,%d", root.DeptId, dept.DeptId)))
}
}
}
return items, nil
}
// DeptType=1:公司类型树
if *query.DeptType == "1" {
companyDepts := make([]*model.SysDeptListModel, 0)
for _, dept := range depts {
if dept.DeptType == 1 {
companyDepts = append(companyDepts, dept)
}
}
// 公司类型的可见根:ParentId=0 或 ParentId 不在 companyDepts 中
companyIdSet := make(map[int64]struct{}, len(companyDepts))
for _, d := range companyDepts {
companyIdSet[d.DeptId] = struct{}{}
}
companyRoots := make([]*model.SysDeptListModel, 0, len(companyDepts))
for _, d := range companyDepts {
if d.ParentId == 0 {
companyRoots = append(companyRoots, d)
continue
}
if _, ok := companyIdSet[d.ParentId]; !ok {
companyRoots = append(companyRoots, d)
}
}
// rootMap:原 rootDepts 的索引,用于补 ancestors
rootMap := make(map[int64]*model.SysDeptListModel, len(rootDepts))
for _, root := range rootDepts {
rootMap[root.DeptId] = root
}
// 公司子树递归
var buildCompanySubTree func(parentDept *model.SysDeptTreeModel, ancestors string) ([]*model.SysDeptTreeModel, error)
buildCompanySubTree = func(parentDept *model.SysDeptTreeModel, ancestors string) ([]*model.SysDeptTreeModel, error) {
data := make([]*model.SysDeptTreeModel, 0)
for _, dept := range companyDepts {
if dept.ParentId == parentDept.DeptId {
item := l.deptTreeItem(dept, ancestors+","+fmt.Sprintf("%d", dept.DeptId))
children, err := buildCompanySubTree(item, item.Ancestors)
if err != nil {
return nil, err
}
item.Children = children
data = append(data, item)
}
}
return data, nil
}
for _, root := range companyRoots {
ancestors := fmt.Sprintf("%d", root.DeptId)
if visibleRoot, ok := rootMap[root.ParentId]; ok {
ancestors = fmt.Sprintf("%d,%d", visibleRoot.DeptId, root.DeptId)
}
rootItem := l.deptTreeItem(root, ancestors)
children, err := buildCompanySubTree(rootItem, rootItem.Ancestors)
if err != nil {
return nil, err
}
rootItem.Children = children
items = append(items, rootItem)
}
return items, nil
}
return make([]*model.SysDeptTreeModel, 0), nil
}
// deptTreeItem 构建部门树项
func (l *sSysDept) deptTreeItem(dept *model.SysDeptListModel, ancestors string) *model.SysDeptTreeModel {
return &model.SysDeptTreeModel{
DeptId: dept.DeptId,
ParentId: dept.ParentId,
DeptName: dept.DeptName,
Key: fmt.Sprintf("%d", dept.DeptId),
Children: nil,
Ancestors: ancestors,
DeptType: dept.DeptType,
}
}
// 递归构建结构
func (l *sSysDept) RecursionDeptIds(ctx context.Context, parentId int64, deptList []*model.SysDeptListModel, data *[]int64) (err error) {
for _, dept := range deptList {
if dept.ParentId == parentId {
*data = append(*data, dept.DeptId)
err := l.RecursionDeptIds(ctx, dept.DeptId, deptList, data)
if err != nil {
return err
}
}
}
return
}
// 根据父部门id获取部门列表
func (l *sSysDept) GetDeptIdsByParentId(ctx context.Context, parentId int64) (ids []int64, err error) {
depts, _, err := l.GetDeptList(ctx, model.SysDeptListParam{})
if err != nil {
return nil, err
}
ids = make([]int64, 0)
err = l.RecursionDeptIds(ctx, parentId, depts, &ids)
if err != nil {
return nil, err
}
// g.Log().Infof(ctx, "sSysDept.GetDeptIdsByParentId 获取部门列表: ids:%+v", ids)
return ids, nil
}
// AddDept 添加部门
func (l *sSysDept) AddDept(ctx context.Context, dept *model.SysDeptAddModel) (deptId int64, err error) {
user := contexts.GetUser(ctx)
if user == nil {
return 0, gerror.NewCode(consts.CodeLoginExpired, "登录已过期")
}
if dept.DeptType == 1 {
isCompany, err := l.ValidateParentIsCompany(ctx, dept.ParentId)
if err != nil {
g.Log().Errorf(ctx, "sSysDept.AddDept ValidateParentIsCompany err: %v, parentId:%d, dept:%+v", err, dept.ParentId, dept)
return 0, err
}
if !isCompany {
return 0, gerror.New("上级部门必须是公司")
}
}
data := do.SysDept{}
gconv.Struct(dept, &data)
data.CreatedDept = user.DeptId
data.CreatedBy = user.ID
data.CreatedAt = gtime.Now()
data.UpdatedBy = user.ID
data.UpdatedAt = gtime.Now()
data.TenantId = user.TenantId
deptId, err = l.Model(ctx).Data(data).InsertAndGetId()
if err != nil {
return 0, err
}
event.EventsInstance().Emit(ctx, consts.EventKeyDBSysDeptCreate, deptId)
// 刷新部门祖先
err = l.RefreshDeptAncestors(ctx)
if err != nil {
return 0, err
}
return deptId, nil
}
// EditDept 编辑部门
func (l *sSysDept) EditDept(ctx context.Context, dept *model.SysDeptEditModel) (deptId int64, err error) {
user := contexts.GetUser(ctx)
if user == nil {
return dept.DeptId, gerror.NewCode(consts.CodeLoginExpired, "登录已过期")
}
// 查询现有数据
existingDept, err := l.GetDeptById(ctx, dept.DeptId)
if err != nil {
g.Log().Errorf(ctx, "sSysDept.EditDept GetDeptById err: %v, deptId:%d, dept:%+v", err, dept.DeptId, gconv.String(dept))
return 0, err
}
if existingDept == nil || existingDept.DeptId == 0 || existingDept.DeptId != dept.DeptId {
g.Log().Warningf(ctx, "sSysDept.EditDept GetDeptById err: %v, deptId:%d, dept:%+v", err, dept.DeptId, gconv.String(dept))
return 0, gerror.New("部门不存在")
}
newParentId := existingDept.ParentId
if dept.ParentId != nil {
newParentId = *dept.ParentId
}
if dept.DeptType != nil && *dept.DeptType == 1 && *dept.ParentId != 0 {
isCompany, err := l.ValidateParentIsCompany(ctx, newParentId)
if err != nil {
return 0, err
}
if !isCompany {
return 0, gerror.New("上级组织必须是公司")
}
}
if dept.DeptType != nil && *dept.DeptType != existingDept.DeptType {
if existingDept.DeptType == 1 {
return 0, gerror.New("组织类型不能修改")
}
}
data := do.SysDept{}
gconv.Struct(dept, &data)
data.UpdatedBy = user.ID
data.UpdatedAt = gtime.Now()
_, err = l.Model(ctx).Data(data).Where(dao.SysDept.Columns().DeptId, dept.DeptId).Update()
if err != nil {
return dept.DeptId, err
}
event.EventsInstance().Emit(ctx, consts.EventKeyDBSysDeptUpdate, dept.DeptId)
// 刷新部门祖先
err = l.RefreshDeptAncestors(ctx)
if err != nil {
return 0, err
}
return dept.DeptId, nil
}
// DeleteDept 删除部门
func (l *sSysDept) DeleteDept(ctx context.Context, dept *model.SysDeptDeleteModel) (deptId int64, err error) {
count, err := l.ModelQuery(ctx).Where(dao.SysDept.Columns().ParentId, dept.DeptId).Count()
if err != nil {
return dept.DeptId, err
}
if count > 0 {
return dept.DeptId, gerror.NewCode(consts.CodeDeptHasSub, "该部门下有子部门,不能删除")
}
// 部门下有用户,不能删除
userList, _, err := service.SysUser().List(ctx, &request.PageInfo{
Page: 1,
PageSize: 100,
}, &model.UserListParam{
DeptId: dept.DeptId,
})
if err != nil {
return dept.DeptId, err
}
if len(userList) > 0 {
return dept.DeptId, gerror.New("该部门下有用户,不能删除")
}
err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
err = service.AgentEnterprise().Delete(ctx, &model.TAgentEnterpriseDeleteParam{
DeptId: dept.DeptId,
})
if err != nil {
g.Log().Errorf(ctx, "sSysDept.DeleteDept Delete err: %v, deptId:%d, Input:%+v", err, dept.DeptId, dept)
return err
}
_, err = l.Model(ctx).Where(dao.SysDept.Columns().DeptId, dept.DeptId).Delete()
if err != nil {
return err
}
return nil
})
event.EventsInstance().Emit(ctx, consts.EventKeyDBSysDeptDelete, dept.DeptId)
return dept.DeptId, nil
}
// 刷新部门 ancestors
func (l *sSysDept) RefreshDeptAncestors(ctx context.Context) (err error) {
var depts []*model.SysDeptViewModel
err = l.ModelQuery(ctx, &handler.Option{
FilterTenant: true,
FilterAuth: false,
}).Scan(&depts)
if err != nil {
return err
}
for _, dept := range depts {
ancestors := ""
l.GetParentIDAncestors(ctx, depts, dept.ParentId, &ancestors)
if ancestors != dept.Ancestors {
_, err = l.Model(ctx).Data(do.SysDept{
Ancestors: ancestors,
}).Where(dao.SysDept.Columns().DeptId, dept.DeptId).Update()
if err != nil {
return err
}
event.EventsInstance().Emit(ctx, consts.EventKeyDBSysDeptUpdate, dept.DeptId)
g.Log().Infof(ctx, "sSysDept.RefreshDeptAncestors 刷新部门祖先: deptId:%d, ancestors:%s", dept.DeptId, ancestors)
}
}
return nil
}
// GetParentIDAncestors 获取部门祖先
func (l *sSysDept) GetParentIDAncestors(ctx context.Context, depts []*model.SysDeptViewModel, printId int64, ancestors *string) (err error) {
for _, dept := range depts {
if dept.DeptId == printId {
*ancestors = fmt.Sprintf("%d", dept.DeptId) + "," + *ancestors
l.GetParentIDAncestors(ctx, depts, dept.ParentId, ancestors)
return nil
}
}
*ancestors = "0," + *ancestors
return nil
}
// GetDeptListByIds 根据部门ID列表获取部门列表
func (l *sSysDept) GetDeptListByIds(ctx context.Context, ids []int64) (depts []*model.SysDeptListModel, err error) {
err = l.ModelQuery(ctx).WhereIn(dao.SysDept.Columns().DeptId, ids).Scan(&depts)
if err != nil {
return nil, err
}
return depts, nil
}
// 验证上级是否是公司
func (l *sSysDept) ValidateParentIsCompany(ctx context.Context, parentId int64) (isCompany bool, err error) {
dept, err := l.GetDeptById(ctx, parentId)
if err != nil {
return false, err
}
return dept.DeptType == 1 || dept.ParentId == 0, nil
}
// 获取上级公司名称
func (l *sSysDept) getParentCompanyInfo(ctx context.Context, depts []*model.SysDeptListModel, deptId int64) *model.SysDeptListModel {
var topDept *model.SysDeptListModel
for _, dept := range depts {
if dept.ParentId == 0 {
topDept = dept
}
if dept.DeptId == deptId {
if dept.ParentId == 0 {
return dept
}
if dept.DeptType == 1 {
return dept
}
return l.getParentCompanyInfo(ctx, depts, dept.ParentId)
}
}
return topDept
}
// 获取组织公司Map
func (l *sSysDept) GetDeptCompanyMap(ctx context.Context) (map[int64]string, error) {
depts, _, err := l.GetDeptList(ctx, model.SysDeptListParam{})
if err != nil {
return nil, err
}
companyMap := make(map[int64]string)
for _, dept := range depts {
if dept.ParentId == 0 {
companyMap[0] = dept.DeptName
}
if dept.DeptType == 1 {
companyMap[dept.DeptId] = dept.DeptName
} else if dept.ParentId == 0 {
companyMap[dept.DeptId] = dept.DeptName
} else {
parentDept := l.getParentCompanyInfo(ctx, depts, dept.DeptId)
if parentDept != nil {
companyMap[dept.DeptId] = parentDept.DeptName
} else {
companyMap[dept.DeptId] = ""
}
}
}
return companyMap, nil
}
// 获取上级公司组织信息
func (l *sSysDept) GetParentCompanyInfo(ctx context.Context, deptId int64) *model.SysDeptListModel {
depts, _, err := l.GetDeptList(ctx, model.SysDeptListParam{})
if err != nil {
g.Log().Errorf(ctx, "sSysDept.GetParentCompanyInfo GetDeptList err: %v, deptId:%d", err, deptId)
return nil
}
return l.getParentCompanyInfo(ctx, depts, deptId)
}