flipped-aurora/gin-vue-admin · error

该岗位下存在用户,不允许删除

Error message

该岗位下存在用户,不允许删除

What it means

DeleteSysPosition counts rows in sys_user_position referencing the position; if any user is still bound to it, the delete is refused with this error to avoid orphaning user-position assignments. The delete only proceeds when joinCount is 0.

Source

Thrown at server/service/system/sys_position.go:46

		"name":   pos.Name,
		"code":   pos.Code,
		"sort":   pos.Sort,
		"status": pos.Status,
		"remark": pos.Remark,
	}).Error
}

// DeleteSysPosition 删除岗位, 已有用户绑定时禁止删除
func (s *SysPositionService) DeleteSysPosition(ctx context.Context, id uint) (err error) {
	if id == 0 {
		return errors.New("岗位ID不能为空")
	}
	var joinCount int64
	if err = global.GVA_DB.WithContext(ctx).Model(&system.SysUserPosition{}).Where("sys_position_id = ?", id).Count(&joinCount).Error; err != nil {
		return err
	}
	if joinCount > 0 {
		return errors.New("该岗位下存在用户,不允许删除")
	}
	return global.GVA_DB.WithContext(ctx).Delete(&system.SysPosition{}, id).Error
}

// GetSysPosition 获取单个岗位
func (s *SysPositionService) GetSysPosition(ctx context.Context, id uint) (pos system.SysPosition, err error) {
	err = global.GVA_DB.WithContext(ctx).First(&pos, id).Error
	return
}

// GetSysPositionList 分页获取岗位列表
func (s *SysPositionService) GetSysPositionList(ctx context.Context, info systemReq.SysPositionSearch) (list []system.SysPosition, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	db := global.GVA_DB.WithContext(ctx).Model(&system.SysPosition{})
	if info.Name != "" {
		db = db.Where("name LIKE ?", "%"+info.Name+"%")
	}

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Unassign users from the position first (SetPositionUsers with an empty/adjusted list, or remove user-position bindings).
  2. Query bindings to see affected users: SELECT * FROM sys_user_position WHERE sys_position_id = <id>.
  3. Reassign affected users to a replacement position, then retry the delete.

Example fix

// before
await positionApi.deletePosition(id) // fails: users still bound
// after
const users = await positionApi.getPositionUsers(id)
await positionApi.setPositionUsers({ positionId: id, userIds: [] }) // clear bindings
await positionApi.deletePosition(id)
Defensive patterns

Strategy: validation

Validate before calling

const users = (await positionApi.getPositionUsers(id)).data || []
if (users.length > 0) {
  if (!confirm(`该岗位仍有 ${users.length} 名用户,需先解除绑定,是否继续清空并删除?`)) return
  await positionApi.setPositionUsers({ positionId: id, userIds: [] })
}
await positionApi.deletePosition({ id })

Try / catch

try {
  await positionApi.deletePosition({ id })
} catch (e) {
  if (e.msg === '该岗位下存在用户,不允许删除') {
    showUnassignUsersDialog(id) // walk user through clearing bindings first
  } else throw e
}

Prevention

When it happens

Trigger: Calling DELETE /position/deletePosition for a position id that has at least one row in sys_user_position (i.e. at least one user assigned to that position).

Common situations: Trying to clean up obsolete positions that are still assigned to employees; deleting via script without checking bindings; cascading org restructures where users were not reassigned first.

Related errors


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