{"record":{"id":"85b2e8a19666b3b9","repo":"jeecgboot/JeecgBoot","slug":"500-85b2e8","errorCode":"500","errorMessage":"租户不存在！","messagePattern":"租户不存在！","errorType":"exception","errorClass":"JeecgBootException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java","lineNumber":1091,"sourceCode":"            if (response.getIntValue(ERR_CODE) == 0) {\n                //将userTicket也返回，用于获取手机号\n                String userTicket = response.getString(\"user_ticket\");\n                String appUserId = response.getString(\"UserId\");\n                map.put(\"userTicket\",userTicket);\n                map.put(\"appUserId\",appUserId);\n                return map;\n            }\n        }\n        return null;\n    }\n\n    /**\n     * OAuth2登录，成功返回登录的SysUser，失败返回null\n     */\n    public SysUser oauth2Login(String code,Integer tenantId) {\n        Long count = tenantMapper.tenantIzExist(tenantId);\n        if(ObjectUtil.isEmpty(count) || 0 == count){\n            throw new JeecgBootException(\"租户不存在！\");\n        }\n        // 代码逻辑说明: [QQYUN-3440]新建企业微信和钉钉配置表，通过租户模式隔离------------\n        SysThirdAppConfig config = configMapper.getThirdConfigByThirdType(tenantId, MessageTypeEnum.QYWX.getType());\n        String accessToken = this.getAppAccessToken(config);\n        if (accessToken == null) {\n            return null;\n        }\n        Map<String,String> map = this.getUserIdByThirdCode(code, accessToken);\n        if (null != map) {\n            //企业微信需要通过userTicket获取用户信息\n            String appUserId = map.get(\"appUserId\");\n            String userTicket = map.get(\"userTicket\");\n            // 判断第三方用户表有没有这个人\n            LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();\n            queryWrapper.eq(SysThirdAccount::getThirdUserId, appUserId);\n            queryWrapper.eq(SysThirdAccount::getThirdType, THIRD_TYPE);\n            queryWrapper.eq(SysThirdAccount::getTenantId, tenantId);\n            SysThirdAccount thirdAccount = sysThirdAccountService.getOne(queryWrapper);","sourceCodeStart":1073,"sourceCodeEnd":1109,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java#L1073-L1109","documentation":"Identical guard to error 260 but for WeChat Enterprise (企业微信) OAuth login in ThirdAppWechatEnterpriseServiceImpl.oauth2Login. The system queries tenantMapper.tenantIzExist(tenantId) and throws JeecgBootException (HTTP 500) when the tenant does not exist. This is the multi-tenant validation that runs before any WeChat Enterprise API call.","triggerScenarios":"Call oauth2Login(code, tenantId) with a tenantId that has no matching row in sys_tenant. Same triggers as error 260: frontend sends wrong/default tenantId, tenant was deleted, fresh DB without seeded tenant data, or manually crafted URL with invalid tenant parameter.","commonSituations":"WeChat Enterprise login link was generated for a tenant that was subsequently removed. Multi-tenant deployment where the WeChat Enterprise corp configuration is tenant-specific but the tenantId routing is misconfigured. Frontend tenant selector was bypassed or returned an unexpected value.","solutions":["Inspect the login request payload in browser DevTools to confirm the tenantId value being sent.","Verify the tenant exists: SELECT id, name, status FROM sys_tenant WHERE id = <tenantId>.","If using a single-tenant setup, ensure the default tenant (ID 0 or 1) is used and seeded in the database.","Configure the frontend WeChat Enterprise login flow to always include a valid, existing tenantId from the tenant selector or system config."],"exampleFix":"// before: no pre-check on tenantId before OAuth redirect\nwindow.location.href = `${wechatOAuthUrl}?appid=CORPID&redirect_uri=CALLBACK`;\n\n// after: validate tenantId is set before initiating WeChat OAuth\nif (!tenantId) {\n  message.error('租户信息缺失，无法登录');\n  return;\n}\nwindow.location.href = `${wechatOAuthUrl}?appid=CORPID&redirect_uri=CALLBACK&state=${tenantId}`;","handlingStrategy":"validation","validationCode":"// Before calling oauth2Login, validate tenant existence\npublic boolean validateTenant(Integer tenantId) {\n    if (tenantId == null || tenantId <= 0) {\n        return false;\n    }\n    Long count = tenantMapper.tenantIzExist(tenantId);\n    return count != null && count > 0;\n}","typeGuard":"public boolean isValidTenantId(Integer tenantId) {\n    return tenantId != null && tenantId > 0;\n}","tryCatchPattern":"try {\n    SysUser user = thirdAppWechatEnterpriseService.oauth2Login(code, tenantId);\n    if (user == null) {\n        return Result.error(\"企业微信登录失败\");\n    }\n    return Result.OK(user);\n} catch (JeecgBootException e) {\n    if (e.getMessage().contains(\"租户不存在\")) {\n        return Result.error(\"租户不存在，请确认租户ID\");\n    }\n    return Result.error(e.getMessage());\n}","preventionTips":["Ensure the frontend WeChat Enterprise login flow always passes a valid tenantId.","Seed sys_tenant with at least one valid tenant during deployment.","Validate tenant existence in the controller layer before calling the service.","Handle the error gracefully on the frontend with a redirect to the tenant selection page."],"tags":["wechat-enterprise","oauth","multi-tenant","authentication","jeecg-boot"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}