sync: 同步 v1.0.4 并脱敏配置与镜像

This commit is contained in:
MiFaZhan
2026-10-29 14:36:49 +08:00
parent 743e8e6e6e
commit 2206a393f7
516 changed files with 18119 additions and 2253 deletions
+117 -23
View File
@@ -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
}