{"record":{"id":"630110980b25472d","repo":"flipped-aurora/gin-vue-admin","slug":"error-630110","errorCode":null,"errorMessage":"用户不存在","messagePattern":"用户不存在","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_api_token.go","lineNumber":19,"sourceCode":"package system\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/system\"\n\tsysReq \"github.com/flipped-aurora/gin-vue-admin/server/model/system/request\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/utils\"\n\t\"github.com/golang-jwt/jwt/v5\"\n\t\"time\"\n)\n\ntype ApiTokenService struct{}\n\nfunc (apiVersion *ApiTokenService) CreateApiToken(ctx context.Context, apiToken system.SysApiToken, days int) (string, error) {\n\tvar user system.SysUser\n\tif err := global.GVA_DB.WithContext(ctx).Preload(\"Authorities\").Where(\"id = ?\", apiToken.UserID).First(&user).Error; err != nil {\n\t\treturn \"\", errors.New(\"用户不存在\")\n\t}\n\n\thasAuth := false\n\tfor _, auth := range user.Authorities {\n\t\tif auth.AuthorityId == apiToken.AuthorityID {\n\t\t\thasAuth = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !hasAuth && user.AuthorityId != apiToken.AuthorityID {\n\t\treturn \"\", errors.New(\"用户不具备该角色权限\")\n\t}\n\n\tj := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一不同的部分是过期时间\n\n\texpireTime := time.Duration(days) * 24 * time.Hour\n\tif days == -1 {\n\t\texpireTime = 100 * 365 * 24 * time.Hour","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_api_token.go#L1-L37","documentation":"CreateApiToken issues a custom-lifetime JWT for automation, but first verifies the target user exists and Preloads their Authorities. If the query on sys_users by apiToken.UserID returns any error (record not found or DB error), it returns \"用户不存在\" without issuing a token.","triggerScenarios":"Calling the API-token creation endpoint with a UserID that does not exist in sys_users (deleted user, wrong ID, or an ID from a different database environment).","commonSituations":"Creating a CI token after the user account was deleted; copying a user ID from a staging dump into production; a hard-coded UserID in a script left over from a rebuilt database.","solutions":["Verify the user ID exists (SELECT id FROM sys_users WHERE id = ?) and use a valid one.","Re-create the user account if it was deleted, then request the token.","Confirm you are pointing at the intended database (config mismatch between environments)."],"exampleFix":"// before\nsvc.CreateApiToken(ctx, system.SysApiToken{UserID: 9999, AuthorityID: 888}, 30)\n\n// after: resolve the user by username first\nvar user system.SysUser\nif err := global.GVA_DB.WithContext(ctx).Where(\"username = ?\", \"ci-bot\").First(&user).Error; err != nil {\n    return err\n}\nsvc.CreateApiToken(ctx, system.SysApiToken{UserID: user.ID, AuthorityID: 888}, 30)","handlingStrategy":"validation","validationCode":"const user = await getUserById({ id: form.userId })\nif (!user?.data?.user?.ID) throw new Error('目标用户不存在，无法签发 API token')","typeGuard":null,"tryCatchPattern":"try {\n  const token = await createApiToken(form)\n} catch (e) {\n  if (String(e?.msg).includes('用户不存在')) {\n    ElMessage.error('用户 ID 无效：请确认该账号存在且未在当前环境被删除')\n  } else { throw e }\n}","preventionTips":["Resolve users by username at runtime rather than hard-coding user IDs in scripts.","After deleting a user, revoke and regenerate any tokens/scripts referencing their ID.","Keep environment configs separate; don't reuse user IDs across staging/production.","Store the username alongside the token so ownership can be re-verified later."],"tags":["user-not-found","api-token","jwt","gorm"],"backgroundTag":"user-not-found","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}