currentCode(); $query = WxAppModel::where('deleted_at', 0)->where('status', 0); $app = $code !== '' ? $query->where('code', $code)->first() : $query->first(); // 库表命中:解密密钥列后返回 if (!empty($app)) { return $this->loadWithSecrets($app); } // 库表未命中,回落 .env(仅 AppID/名称,不含密钥) $envAppId = trim((string) config('nl.wx.env_app_id', '')); if ($envAppId === '') { // .env 没配 AppID 就没法兜底了,直接抛错 UtilsService::getInstance()->errorThrow('未配置小程序应用(nl_wx_app),请先在后台添加或在 .env 配 WX_APP_ID'); } $envCode = trim((string) config('nl.wx.default_app_code', '')); $envName = trim((string) config('nl.wx.env_app_name', '')); // 兜底场景:AppID 来自 .env,但密钥仍只能从库里按 AppID 找一行来解密 // 这样老项目硬编码密钥的脏习惯不会回到 .env,密钥始终加密入库 $secretRow = WxAppModel::where('app_id', $envAppId) ->where('deleted_at', 0) ->first(['app_secret', 'mch_key', 'mch_private_key']); if (empty($secretRow) || trim((string) ($secretRow['app_secret'] ?? '')) === '') { // 表里既没匹配行、或行里没填密钥,只能报错让运维去后台补 UtilsService::getInstance()->errorThrow( '小程序 AppSecret 未配置:请打开侧栏「小程序 → 应用配置」,新增/编辑 AppID=' . $envAppId . ' 的记录并填写 AppSecret(密钥加密入库,不要写进 .env)' ); } $encrypt = FieldEncryptService::getInstance(); return [ 'id' => 0, 'code' => $envCode, 'name' => $envName, 'app_id' => $envAppId, 'app_secret' => $encrypt->decryptFromStorage((string) $secretRow['app_secret'], true), 'mch_id' => '', 'mch_key' => $encrypt->decryptFromStorage((string) ($secretRow['mch_key'] ?? ''), true), 'mch_serial_no' => '', 'mch_private_key' => $encrypt->decryptFromStorage((string) ($secretRow['mch_private_key'] ?? ''), true), 'platform_public_key' => '', 'notify_url' => '', 'template_code' => '', ]; } /** * 当前请求声明的品牌标识 * * 优先级:请求头 X-App-Code > 请求参数 app_code > .env 的 WX_DEFAULT_APP_CODE * 全部为空时返回空串,调用方会改走「取唯一启用行」逻辑 */ public function currentCode(): string { $code = (string) (request()->header('X-App-Code') ?: request()->input('app_code', '')); $code = trim($code); if ($code !== '') { return $code; } // 请求没带品牌标识时回落 .env 默认值(单品牌部署兜底) return trim((string) config('nl.wx.default_app_code', '')); } /** * 把模型行的密钥列解密后转数组返回 */ private function loadWithSecrets($app): array { $app = $app->toArray(); $raw = WxAppModel::where('id', $app['id'])->first(['app_secret', 'mch_key', 'mch_private_key']); $encrypt = FieldEncryptService::getInstance(); $secret = $encrypt->decryptFromStorage($raw['app_secret'] ?? '', true); if (trim((string) $secret) === '') { UtilsService::getInstance()->errorThrow( '小程序 AppSecret 未配置:请打开侧栏「小程序 → 应用配置」,编辑 code=' . ($app['code'] ?? '') . '(AppID=' . ($app['app_id'] ?? '') . ')并填写 AppSecret' ); } $app['app_secret'] = $secret; $app['mch_key'] = $encrypt->decryptFromStorage($raw['mch_key'] ?? '', true); $app['mch_private_key'] = $encrypt->decryptFromStorage($raw['mch_private_key'] ?? '', true); return $app; } }