flipped-aurora/gin-vue-admin · error

父部门不能是自己

Error message

父部门不能是自己

What it means

UpdateSysDepartment rejects an update where the department's ParentId equals its own ID, which would create a self-referencing cycle in the ancestor chain. The guard is a plain equality check before recomputing ancestors.

Source

Thrown at server/service/system/sys_department.go:109

	return nil
}

// CreateSysDepartment 创建部门并自动维护祖级链
func (s *SysDepartmentService) CreateSysDepartment(ctx context.Context, dept *system.SysDepartment) (err error) {
	ancestors, err := s.buildAncestors(ctx, dept.ParentId)
	if err != nil {
		return err
	}
	dept.Ancestors = ancestors
	dept.Children = nil
	return global.GVA_DB.WithContext(ctx).Create(dept).Error
}

// UpdateSysDepartment 更新部门, 若父部门变更则重算本节点祖级链
// 注: 子孙节点的祖级链重算(部门移动)属后续阶段, 此处仅保证本节点正确
func (s *SysDepartmentService) UpdateSysDepartment(ctx context.Context, dept *system.SysDepartment) (err error) {
	if dept.ParentId == dept.ID {
		return errors.New("父部门不能是自己")
	}
	ancestors, err := s.buildAncestors(ctx, dept.ParentId)
	if err != nil {
		return err
	}
	return global.GVA_DB.WithContext(ctx).Model(&system.SysDepartment{}).Where("id = ?", dept.ID).Updates(map[string]interface{}{
		"name":      dept.Name,
		"parent_id": dept.ParentId,
		"ancestors": ancestors,
		"sort":      dept.Sort,
		"leader_id": dept.LeaderId,
		"status":    dept.Status,
	}).Error
}

// DeleteSysDepartment 删除部门, 存在子部门或已有用户归属时禁止删除
func (s *SysDepartmentService) DeleteSysDepartment(ctx context.Context, id uint) (err error) {
	if id == 0 {

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Choose a different parent department that is not the record itself
  2. In the frontend parent selector, exclude the node being edited (and ideally its descendants) from options
  3. If no parent change is intended, leave ParentId unchanged

Example fix

// before (frontend)
const options = allDepartments
// after
const options = allDepartments.filter(d => d.ID !== editingDept.ID)
Defensive patterns

Strategy: validation

Validate before calling

if dept.ParentId == dept.ID {
    return errors.New("department cannot be its own parent")
}

Try / catch

if err := deptService.UpdateSysDepartment(ctx, dept); err != nil {
    if err.Error() == "父部门不能是自己" {
        // prompt user to pick a different parent
    }
    return err
}

Prevention

When it happens

Trigger: Calling UpdateSysDepartment with a SysDepartment whose ParentId == ID, typically from an edit form where the user selected the department itself as its parent.

Common situations: Department tree UI allowing all nodes (including self) in the parent selector; API consumers constructing update payloads programmatically and copying ID into ParentId.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/98244e077dfd9b3e. Report an issue: GitHub.