{"record":{"id":"05e6218cb024d226","repo":"flipped-aurora/gin-vue-admin","slug":"id-05e621","errorCode":null,"errorMessage":"部门ID不能为空","messagePattern":"部门ID不能为空","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_department.go","lineNumber":128,"sourceCode":"\t}\n\tancestors, err := s.buildAncestors(ctx, dept.ParentId)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn global.GVA_DB.WithContext(ctx).Model(&system.SysDepartment{}).Where(\"id = ?\", dept.ID).Updates(map[string]interface{}{\n\t\t\"name\":      dept.Name,\n\t\t\"parent_id\": dept.ParentId,\n\t\t\"ancestors\": ancestors,\n\t\t\"sort\":      dept.Sort,\n\t\t\"leader_id\": dept.LeaderId,\n\t\t\"status\":    dept.Status,\n\t}).Error\n}\n\n// DeleteSysDepartment 删除部门, 存在子部门或已有用户归属时禁止删除\nfunc (s *SysDepartmentService) DeleteSysDepartment(ctx context.Context, id uint) (err error) {\n\tif id == 0 {\n\t\treturn errors.New(\"部门ID不能为空\")\n\t}\n\tif !errors.Is(global.GVA_DB.WithContext(ctx).Where(\"parent_id = ?\", id).First(&system.SysDepartment{}).Error, gorm.ErrRecordNotFound) {\n\t\treturn errors.New(\"存在子部门,不允许删除\")\n\t}\n\tvar userCount int64\n\tif err = global.GVA_DB.WithContext(ctx).Model(&system.SysUser{}).Where(\"dept_id = ?\", id).Count(&userCount).Error; err != nil {\n\t\treturn err\n\t}\n\tif userCount > 0 {\n\t\treturn errors.New(\"该部门下存在用户,不允许删除\")\n\t}\n\tvar joinCount int64\n\tif err = global.GVA_DB.WithContext(ctx).Model(&system.SysUserDepartment{}).Where(\"sys_department_id = ?\", id).Count(&joinCount).Error; err != nil {\n\t\treturn err\n\t}\n\tif joinCount > 0 {\n\t\treturn errors.New(\"该部门下存在用户,不允许删除\")\n\t}","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_department.go#L110-L146","documentation":"DeleteSysDepartment requires a non-zero department ID. Passing 0 (Go's zero value for uint) is treated as 'no ID provided' and rejected before any DB access. This guards against deleting with an unset/unbound parameter.","triggerScenarios":"DeleteSysDepartment(ctx, 0) — e.g. the API path param failed to bind, the frontend sent an empty id, or a struct's ID field was never populated before calling the service.","commonSituations":"Frontend calling delete before the row ID is loaded; gin URI/query binding mismatch so ID stays 0; tests invoking the service with a zero-value struct.","solutions":["Ensure the delete request carries the actual department ID (check the route param / request body)","On the frontend, disable the delete action until the row's ID is available","In code, check id != 0 before calling the service"],"exampleFix":"// before\ndeleteDepartment({ id: dept.id }) // dept.id may be undefined -> 0\n// after\nif (!dept.id) return\ndeleteDepartment({ id: dept.id })","handlingStrategy":"validation","validationCode":"if id == 0 {\n    return errors.New(\"department id is required\")\n}","typeGuard":null,"tryCatchPattern":"if err := deptService.DeleteSysDepartment(ctx, id); err != nil {\n    if err.Error() == \"部门ID不能为空\" {\n        // fix request binding / ensure id is supplied\n    }\n    return err\n}","preventionTips":["Always pass the row's real ID from a loaded record, not a fresh struct","Verify gin route param binding (e.g. :id) matches the handler argument","Disable delete buttons until row data with ID is loaded"],"tags":["department","validation","go"],"backgroundTag":"missing-required-identifier","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}