{"record":{"id":"9320553b25641374","repo":"flipped-aurora/gin-vue-admin","slug":"id-932055","errorCode":null,"errorMessage":"岗位ID不能为空","messagePattern":"岗位ID不能为空","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_position.go","lineNumber":25,"sourceCode":"\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/system\"\n\tsystemReq \"github.com/flipped-aurora/gin-vue-admin/server/model/system/request\"\n\t\"gorm.io/gorm\"\n)\n\ntype SysPositionService struct{}\n\nvar SysPositionServiceApp = new(SysPositionService)\n\n// CreateSysPosition 创建岗位\nfunc (s *SysPositionService) CreateSysPosition(ctx context.Context, pos *system.SysPosition) (err error) {\n\treturn global.GVA_DB.WithContext(ctx).Create(pos).Error\n}\n\n// UpdateSysPosition 更新岗位\nfunc (s *SysPositionService) UpdateSysPosition(ctx context.Context, pos *system.SysPosition) (err error) {\n\tif pos.ID == 0 {\n\t\treturn errors.New(\"岗位ID不能为空\")\n\t}\n\treturn global.GVA_DB.WithContext(ctx).Model(&system.SysPosition{}).Where(\"id = ?\", pos.ID).Updates(map[string]interface{}{\n\t\t\"name\":   pos.Name,\n\t\t\"code\":   pos.Code,\n\t\t\"sort\":   pos.Sort,\n\t\t\"status\": pos.Status,\n\t\t\"remark\": pos.Remark,\n\t}).Error\n}\n\n// DeleteSysPosition 删除岗位, 已有用户绑定时禁止删除\nfunc (s *SysPositionService) DeleteSysPosition(ctx context.Context, id uint) (err error) {\n\tif id == 0 {\n\t\treturn errors.New(\"岗位ID不能为空\")\n\t}\n\tvar joinCount int64\n\tif err = global.GVA_DB.WithContext(ctx).Model(&system.SysUserPosition{}).Where(\"sys_position_id = ?\", id).Count(&joinCount).Error; err != nil {\n\t\treturn err","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_position.go#L7-L43","documentation":"UpdateSysPosition validates that the position struct carries a non-zero ID before issuing the GORM update. A zero ID means the update target is unspecified, so the service returns this error instead of performing an update that would match no rows.","triggerScenarios":"Calling PUT /position/updatePosition (SysPositionService.UpdateSysPosition) with a body whose id field is missing or 0 — e.g. frontend submits a newly created (unsaved) row or omits id from the payload.","commonSituations":"Frontend edit dialog losing the row's id after refresh; JSON field name mismatch (id vs ID) so the field deserializes to 0; constructing SysPosition in code without setting ID.","solutions":["Ensure the request body includes the position's numeric id before calling the update API.","Check frontend form binding so the row's id is carried into the payload.","In Go code, fetch the position first (GetSysPosition) and set pos.ID before updating."],"exampleFix":"// before\npositionApi.updatePosition({ name: 'Engineer', code: 'ENG' }) // no id\n// after\npositionApi.updatePosition({ ID: 3, name: 'Engineer', code: 'ENG' })","handlingStrategy":"validation","validationCode":"if (!form.ID || form.ID <= 0) {\n  alert('缺少岗位ID，无法更新')\n  return\n}\nawait positionApi.updatePosition(form)","typeGuard":"function hasValidPositionId(pos) {\n  return typeof pos?.ID === 'number' && pos.ID > 0\n}","tryCatchPattern":"try {\n  await positionApi.updatePosition(form)\n} catch (e) {\n  if (e.msg === '岗位ID不能为空') {\n    alert('请先保存或选择一个已有岗位再修改')\n  } else throw e\n}","preventionTips":["Always bind the row's ID into the edit form payload.","Disable the update action for unsaved (new) rows.","Verify JSON field names (ID/id) match what the backend struct expects."],"tags":["go","gin-vue-admin","position","validation"],"backgroundTag":"missing-required-id","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}