sync: 同步 v1.0.4 并脱敏配置与镜像
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// package system
|
||||
// @Link https://github.com/xiujiecn/xiu-admin
|
||||
// @Copyright Copyright (c) 2025 LiXiujie
|
||||
// @Author Lxj <li@xiujie.cn>
|
||||
// @Author Lxj <xxx@example.com>
|
||||
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
|
||||
package system
|
||||
|
||||
@@ -145,6 +145,9 @@ func (l *sSysDept) GetDeptFullTree(ctx context.Context, query model.SysDeptFullT
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validateDeptHierarchy(depts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buildSysDeptFullTree(depts), nil
|
||||
}
|
||||
|
||||
@@ -271,6 +274,9 @@ func (l *sSysDept) GetDeptTree(ctx context.Context, query model.SysDeptTreeParam
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validateDeptHierarchy(depts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(depts) == 0 {
|
||||
return make([]*model.SysDeptTreeModel, 0), nil
|
||||
}
|
||||
@@ -401,16 +407,46 @@ func (l *sSysDept) deptTreeItem(dept *model.SysDeptListModel, ancestors string)
|
||||
|
||||
// 递归构建结构
|
||||
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
|
||||
if err = validateDeptHierarchy(deptList); err != nil {
|
||||
return err
|
||||
}
|
||||
var walk func(int64)
|
||||
walk = func(currentId int64) {
|
||||
for _, dept := range deptList {
|
||||
if dept.ParentId == currentId {
|
||||
*data = append(*data, dept.DeptId)
|
||||
walk(dept.DeptId)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
walk(parentId)
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateDeptHierarchy(depts []*model.SysDeptListModel) error {
|
||||
parents := make(map[int64]int64, len(depts))
|
||||
for _, dept := range depts {
|
||||
parents[dept.DeptId] = dept.ParentId
|
||||
}
|
||||
checked := make(map[int64]bool, len(depts))
|
||||
for deptId := range parents {
|
||||
seen := make(map[int64]bool)
|
||||
for currentId := deptId; currentId != 0 && !checked[currentId]; {
|
||||
if seen[currentId] {
|
||||
return gerror.New("组织层级存在循环引用")
|
||||
}
|
||||
seen[currentId] = true
|
||||
parentId, exists := parents[currentId]
|
||||
if !exists {
|
||||
break
|
||||
}
|
||||
currentId = parentId
|
||||
}
|
||||
for visitedId := range seen {
|
||||
checked[visitedId] = true
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 根据父部门id获取部门列表
|
||||
@@ -434,7 +470,7 @@ func (l *sSysDept) AddDept(ctx context.Context, dept *model.SysDeptAddModel) (de
|
||||
if user == nil {
|
||||
return 0, gerror.NewCode(consts.CodeLoginExpired, "登录已过期")
|
||||
}
|
||||
if dept.DeptType == 1 {
|
||||
if dept.DeptType == 1 && dept.ParentId != 0 {
|
||||
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)
|
||||
@@ -486,8 +522,20 @@ func (l *sSysDept) EditDept(ctx context.Context, dept *model.SysDeptEditModel) (
|
||||
newParentId := existingDept.ParentId
|
||||
if dept.ParentId != nil {
|
||||
newParentId = *dept.ParentId
|
||||
var parentDepts []*model.SysDeptViewModel
|
||||
err = l.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}).Scan(&parentDepts)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err = validateDeptParent(dept.DeptId, newParentId, parentDepts); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
if dept.DeptType != nil && *dept.DeptType == 1 && *dept.ParentId != 0 {
|
||||
newDeptType := existingDept.DeptType
|
||||
if dept.DeptType != nil {
|
||||
newDeptType = *dept.DeptType
|
||||
}
|
||||
if newDeptType == 1 && newParentId != 0 {
|
||||
isCompany, err := l.ValidateParentIsCompany(ctx, newParentId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -576,7 +624,9 @@ func (l *sSysDept) RefreshDeptAncestors(ctx context.Context) (err error) {
|
||||
}
|
||||
for _, dept := range depts {
|
||||
ancestors := ""
|
||||
l.GetParentIDAncestors(ctx, depts, dept.ParentId, &ancestors)
|
||||
if err = l.GetParentIDAncestors(ctx, depts, dept.ParentId, &ancestors); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ancestors != dept.Ancestors {
|
||||
_, err = l.Model(ctx).Data(do.SysDept{
|
||||
@@ -594,17 +644,50 @@ func (l *sSysDept) RefreshDeptAncestors(ctx context.Context) (err error) {
|
||||
|
||||
// GetParentIDAncestors 获取部门祖先
|
||||
func (l *sSysDept) GetParentIDAncestors(ctx context.Context, depts []*model.SysDeptViewModel, printId int64, ancestors *string) (err error) {
|
||||
parents := make(map[int64]int64, len(depts))
|
||||
for _, dept := range depts {
|
||||
if dept.DeptId == printId {
|
||||
*ancestors = fmt.Sprintf("%d", dept.DeptId) + "," + *ancestors
|
||||
l.GetParentIDAncestors(ctx, depts, dept.ParentId, ancestors)
|
||||
return nil
|
||||
parents[dept.DeptId] = dept.ParentId
|
||||
}
|
||||
seen := make(map[int64]bool)
|
||||
for printId != 0 {
|
||||
if seen[printId] {
|
||||
return gerror.New("组织层级存在循环引用")
|
||||
}
|
||||
seen[printId] = true
|
||||
parentId, exists := parents[printId]
|
||||
if !exists {
|
||||
break
|
||||
}
|
||||
*ancestors = fmt.Sprintf("%d,", printId) + *ancestors
|
||||
printId = parentId
|
||||
}
|
||||
*ancestors = "0," + *ancestors
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateDeptParent(deptId, parentId int64, depts []*model.SysDeptViewModel) error {
|
||||
parents := make(map[int64]int64, len(depts))
|
||||
for _, dept := range depts {
|
||||
parents[dept.DeptId] = dept.ParentId
|
||||
}
|
||||
seen := make(map[int64]bool)
|
||||
for parentId != 0 {
|
||||
if parentId == deptId {
|
||||
return gerror.New("上级组织不能是当前组织或其下级组织")
|
||||
}
|
||||
if parentId < 0 || seen[parentId] {
|
||||
return gerror.New("组织层级存在循环引用")
|
||||
}
|
||||
seen[parentId] = true
|
||||
next, exists := parents[parentId]
|
||||
if !exists {
|
||||
return gerror.New("上级组织不存在")
|
||||
}
|
||||
parentId = next
|
||||
}
|
||||
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)
|
||||
@@ -620,25 +703,36 @@ func (l *sSysDept) ValidateParentIsCompany(ctx context.Context, parentId int64)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if dept == nil || dept.DeptId == 0 {
|
||||
return false, gerror.New("上级组织不存在")
|
||||
}
|
||||
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
|
||||
byID := make(map[int64]*model.SysDeptListModel, len(depts))
|
||||
for _, dept := range depts {
|
||||
byID[dept.DeptId] = dept
|
||||
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)
|
||||
}
|
||||
seen := make(map[int64]bool)
|
||||
for deptId != 0 {
|
||||
if seen[deptId] {
|
||||
return nil
|
||||
}
|
||||
seen[deptId] = true
|
||||
dept, exists := byID[deptId]
|
||||
if !exists {
|
||||
break
|
||||
}
|
||||
if dept.ParentId == 0 || dept.DeptType == 1 {
|
||||
return dept
|
||||
}
|
||||
deptId = dept.ParentId
|
||||
}
|
||||
return topDept
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user