input('third_user_id'); // bps_third_user的id // // $googleOAuthService = new GoogleOAuthService(); // $hasThirdUser = $googleOAuthService->getCustomerList($thirdUserId); // if (!$hasThirdUser) { // return $this->errorResponse(300, 'Invalid state parameter'); // } // return $this->successResponse($hasThirdUser); // // } //调试用 public function getCustomerList(Request $request) { $merchantId = $request->input('merchant_id'); // bps_third_user的id $googleOAuthService = new GoogleOAuthService(); $hasThirdUser = $googleOAuthService->getCustomerListNew($merchantId); if (!$hasThirdUser) { return $this->errorResponse(300, 'Invalid state parameter'); } return $this->successResponse($hasThirdUser); } public function accessibleCustomers(Request $request) { $options = $request->all(); $options['refresh_token'] = $request->refresh_token; $options['login_customer_id'] = $request->login_customer_id; // 继续处理 Google Ads API 操作 return $this->listAccessibleCustomers($options); } public function accountHierarchy(Request $request) { $options = $request->all(); $options['refresh_token'] = $request->refresh_token; // $options['login_customer_id'] = $request->login_customer_id; $options['login_customer_id'] = $request->input('login_customer_id'); $options['manager_customer_id'] = $request->input('manager_customer_id') !== null ? $request->input('manager_customer_id') : null; // 继续处理 Google Ads API 操作 return $this->getAccountHierarchy($options); } //另一种方案,暂不启用 public function handleBinding(Request $request) { $options = $request->all(); $options['jwtClaims'] = $request->jwtClaims; // dump($options,22222222); // token即uuid 例如:f47ac10b-58cc-4372-a567-0e02b2c3d479 $redisKey = self::REDIS_KEY_PREFIX . $options['token']; // 尝试从 Redis 中获取缓存值 $refresh_token = Redis::get($redisKey); // dump($redisKey, $refresh_token, 444444); // return $this->successResponse($refresh_token); if ($refresh_token) { $options['refresh_token'] = $refresh_token; $googleAdsAccounts = $this->getAccountHierarchyForBind($options); $googleOAuthService = new GoogleOAuthService(); $hasThirdUser = $googleOAuthService->getCustomerListNew($options['jwtClaims']['merchant_id']); // 初始化返回结果数组 $ad_accounts = []; if (!empty($hasThirdUser)) { // 先将 $hasThirdUser 转换为一个 account_id => true 的映射数组 $thirdUserAccounts = []; foreach ($hasThirdUser as $user) { $thirdUserAccounts[$user['account_id']] = true; } // 遍历 $googleAdsAccounts 进行合并和匹配 foreach ($googleAdsAccounts as $login_customer_id => $accounts) { // dump($accounts); if (!empty($accounts[$login_customer_id])) { foreach ($accounts[$login_customer_id] as $account) { $account_id = $account['account_id']; $bind = isset($thirdUserAccounts[$account_id]) ? 1 : 0; // 如果匹配则 bind 为 true $ad_accounts[] = [ 'account_id' => $account['account_id'], 'name' => $account['account_name'], 'currency' => $account['currency'], 'bind' => $bind, 'login_customer_id' => $login_customer_id, ]; } } } } else { // 遍历 $googleAdsAccounts 进行合并和匹配 foreach ($googleAdsAccounts as $login_customer_id => $accounts) { if (!empty($accounts[$login_customer_id])) { foreach ($accounts[$login_customer_id] as $account) { $account_id = $account['account_id']; $bind = isset($thirdUserAccounts[$account_id]) ? 1 : 0; // 如果匹配则 bind 为 true $ad_accounts[] = [ 'account_id' => $account['account_id'], 'name' => $account['account_name'], 'currency' => $account['currency'], 'bind' => $bind, 'login_customer_id' => $login_customer_id, ]; } } } } // dump($ad_accounts); return $this->successResponse(['ad_accounts' => $ad_accounts, 'total_count' => count($ad_accounts)]); } else { return $this->errorResponse(300, 'token expired'); } } //绑定接口-广告主体下层级账号 public function handleBindingNew(Request $request) { $options = $request->all(); $options['jwtClaims'] = $request->jwtClaims; // dump($options,22222222); // token即uuid 例如:f47ac10b-58cc-4372-a567-0e02b2c3d479 $redisKey = self::REDIS_KEY_PREFIX . $options['token']; // 尝试从 Redis 中获取缓存值 $refresh_token = Redis::get($redisKey); // dump($redisKey, $refresh_token, 444444); // return $this->successResponse($refresh_token); if ($refresh_token || $options['jwtClaims']['merchant_id']) { // $options['refresh_token'] = $refresh_token; // // $googleAdsAccounts = $this->getAccountHierarchyForBind($options); $googleOAuthService = new GoogleOAuthService(); //不论绑定状态 $hasThirdUserAccounts = $googleOAuthService->getCustomerListNew($options['jwtClaims']['merchant_id']); // 初始化返回结果数组 $ad_accounts = []; if (!empty($hasThirdUserAccounts)) { foreach ($hasThirdUserAccounts as $account) { $ad_accounts[] = [ 'account_id' => $account['account_id'], 'name' => $account['account_name'], 'currency' => $account['currency'], 'bind' => $account['is_unbind'], ]; } } else { return $this->successResponse(['ad_accounts' => [], 'total_count' => 0]); } // dump($ad_accounts); return $this->successResponse(['ad_accounts' => $ad_accounts, 'total_count' => count($ad_accounts)]); } else { return $this->errorResponse(300, 'token expired'); } } //绑定接口-广告主体下层级账号 public function bind(Request $request) { $options = $request->all(); $options['jwtClaims'] = $request->jwtClaims; // 获取 bind_accounts 数据 $bindAccounts = $options['bind_accounts'] ?? []; // 检查是否传递了 bind_accounts if (empty($bindAccounts)) { return $this->errorResponse(300, 'No bind_accounts provided'); } $redisKey = self::REDIS_KEY_PREFIX . $options['token']; //$options['token'] 即uuid 例如:f47ac10b-58cc-4372-a567-0e02b2c3d479 // 尝试从 Redis 中获取缓存值 $refresh_token = Redis::get($redisKey); // dump($redisKey, $refresh_token, 444444); // return $this->successResponse($refresh_token); if (!$refresh_token) { return $this->errorResponse(300, 'token expired'); } // $googleAccountInfo = $this->googleOAuthService->getGoogleAccountInfo($refresh_token); // 遍历 bind_accounts,保存或更新到 bps_ads_merchant_relation 表 foreach ($bindAccounts as $account) { $data = [ 'merchant_id' => $options['jwtClaims']['merchant_id'], // 假设merchant_id从jwtClaims中获取 'user_id' => $options['jwtClaims']['uid'], 'account_id' => $account['account_id'], 'account_name' => $account['name'], 'currency' => $account['currency'], 'access_token' => $refresh_token, 'refresh_token' => $refresh_token, 'is_unbind' => 'f' // 假设默认绑定状态为 'f' // 'platform_user_id' => $googleAccountInfo['id'], // 'platform_user_name' => $googleAccountInfo['name'], //ext_info是jsonb 存放 $account['login_customer_id']的键值对 // 'ext_info' => json_encode(['login_customer_id' => $account['login_customer_id']]), ]; $this->googleOAuthService->saveThirdUserAdvertiserNew($data, 1); //授权回来先不初始化广告数据 // 查找是否已经存在该账号的绑定记录 // $existingRelation = \App\Models\AdsMerchantRelation::where('account_id', $account['account_id']) // ->where('merchant_id', $options['jwtClaims']['merchant_id']) // ->first(); // // if ($existingRelation) { // // 如果记录已存在,更新 // $existingRelation->update($data); // } else { // // 如果记录不存在,插入新数据 // \App\Models\AdsMerchantRelation::create($data); // } } return $this->successResponse(['success' => 'Accounts successfully bound']); } // 没调用 管理用户访问权限 public function accountAccess(Request $request) { $options = $request->all(); $options['refresh_token'] = $request->refresh_token; $options['login_customer_id'] = $request->login_customer_id; // 继续处理 Google Ads API 操作 return $this->getAccountAccess($options); } /** * 关联广告客户ID * @throws ApiException */ public function listAccessibleCustomers($options): Response { $resourceName = $this->googleAdsAccountService->runListAccessibleCustomers($options); return $this->successResponse(['links_resource_name' => $resourceName]); } /** * 广告主体下层级账号 * @throws ApiException */ public function getAccountHierarchy($options): Response { if (!isset($options['manager_customer_id'])) { $resourceName = []; $listAccessibleCustomers = $this->googleAdsAccountService->runListAccessibleCustomers($options); foreach ($listAccessibleCustomers as $rootAccountId) { $options['manager_customer_id'] = $rootAccountId; //开发者 $options['login_customer_id'] = $rootAccountId; try { // 获取当前 rootAccountId 的所有账户 $allAccountsByRoot = $this->googleAdsAccountService->runGetAccountHierarchy($options); $resourceName[$rootAccountId] = $allAccountsByRoot; } catch (\Exception $e) { // 记录错误日志并跳过当前循环 Log::error("Error processing rootAccountId {$rootAccountId}: " . $e->getMessage()); continue; } } } else { $resourceName = $this->googleAdsAccountService->runListAccessibleCustomers($options); } return $this->successResponse(['links_resource_name' => $resourceName]); } /** * 绑定接口-广告主体下层级账号 * @throws ApiException */ public function getAccountHierarchyForBind($options) { //TODO 过滤经理账号 2025-2-13 $resourceName = []; $listAccessibleCustomers = $this->googleAdsAccountService->runListAccessibleCustomers($options); foreach ($listAccessibleCustomers as $rootAccountId) { $options['manager_customer_id'] = $rootAccountId; //开发者 $options['login_customer_id'] = $rootAccountId; try { // 获取当前 rootAccountId 的所有账户 $allAccountsByRoot = $this->googleAdsAccountService->runGetAccountHierarchy($options); $resourceName[$rootAccountId] = $allAccountsByRoot; } catch (\Exception $e) { // 记录错误日志并跳过当前循环 Log::error("Binding Account List Error processing rootAccountId {$rootAccountId}: " . $e->getMessage()); continue; } } return $resourceName; } /** * 管理用户访问权限 * @throws ApiException */ public function getAccountAccess($options): Response { // dump($options); $resourceName = $this->googleAdsAccountService->runGetAccountAccess($options); return $this->successResponse(['links_resource_name' => $resourceName]); } // 可以加入一些公共方法 protected function successResponse($data): Response { return Json([ 'code' => 0, 'msg' => 'ok', 'data' => $data, ]); } protected function errorResponse($code, $message, $data = []): Response { return Json([ 'code' => $code, 'msg' => $message ?: 'error', 'data' => $data ]); } }