244 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			244 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | ||
| 
 | ||
| namespace app\event;
 | ||
| 
 | ||
| use app\model\ThirdUser;
 | ||
| use app\model\BpsAdsMerchantRelation;
 | ||
| use app\service\GoogleOAuthService;
 | ||
| use app\service\GoogleAdsAccountService;
 | ||
| use Google\ApiCore\ApiException;
 | ||
| use support\Response;
 | ||
| use support\Redis;
 | ||
| use support\Log;
 | ||
| use DI\Annotation\Inject;
 | ||
| 
 | ||
| 
 | ||
| //use QL\QueryList;
 | ||
| 
 | ||
| 
 | ||
| class GoogleAdsCustomers
 | ||
| {
 | ||
|     /**
 | ||
|      * @Inject
 | ||
|      * @var GoogleOAuthService
 | ||
|      */
 | ||
| 
 | ||
|     private $googleOAuthService;
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * @Inject
 | ||
|      * @var GoogleAdsAccountService
 | ||
|      */
 | ||
| 
 | ||
|     private $googleAdsAccountService;
 | ||
| 
 | ||
|     const event = 'googleads:customers:event';
 | ||
|     const newbind_event = 'googleads:customers:newbind:event';
 | ||
|     const add_queue = 'googleads:customers:add:queue';
 | ||
|     const init_queue = 'googleads:customers:init:queue';
 | ||
| 
 | ||
|     //添加某个root广告账号的全部层级账号 废弃2025-2-13
 | ||
|     public function addRootCustomers()
 | ||
|     {
 | ||
| //        dump($options);
 | ||
|         $thirdUser = ThirdUser::where('is_default', 'f')->where('third_type', 'google')
 | ||
|             ->find();
 | ||
|         if (!$thirdUser || !$thirdUser->access_token) {
 | ||
|             dump('not found third user');
 | ||
|             return;
 | ||
|         }
 | ||
|         $option                  = [];
 | ||
|         $option['refresh_token'] = $thirdUser->access_token;
 | ||
|         $listAccessibleCustomers = $this->googleAdsAccountService->runListAccessibleCustomers($option);
 | ||
| 
 | ||
|         // Add a counter to limit the number of executions
 | ||
|         $executionCount = 0;
 | ||
|         foreach ($listAccessibleCustomers as $rootAccountId) {
 | ||
|             $option['manager_customer_id'] = $rootAccountId;  //开发者
 | ||
|             $option['login_customer_id']   = $rootAccountId;
 | ||
|             try {
 | ||
|                 // 获取当前 rootAccountId 的所有账户
 | ||
|                 $allAccountsByRoot = $this->googleAdsAccountService->runGetAccountHierarchy($option);
 | ||
| //                dump($allAccountsByRoot,333);
 | ||
|                 foreach ($allAccountsByRoot as $rootId => $accounts) {
 | ||
|                     foreach ($accounts as $account) {
 | ||
|                         // Ensure we only execute 10 times
 | ||
|                         if ($executionCount >= 10) {
 | ||
|                             dump('Executed 10 times, stopping further calls.');
 | ||
|                             break 3;  // Break out of both inner and outer loops
 | ||
|                         }
 | ||
| //                        dump($account);
 | ||
|                         $this->googleOAuthService->saveThirdUserAdvertiser(
 | ||
|                             $account['customer_id'],
 | ||
|                             $thirdUser->id,
 | ||
|                             $rootId,
 | ||
|                             $account,
 | ||
|                             $thirdUser->merchant_id
 | ||
|                         );
 | ||
|                         // Increment the counter
 | ||
|                         $executionCount++;
 | ||
|                     }
 | ||
|                 }
 | ||
|                 // 绑定的授权主体全部账号更新后将状态从 'f' 更新为 't'
 | ||
|                 $this->googleOAuthService->updateThirdUserDefault($thirdUser->id, 't');
 | ||
|             } catch (\Exception $e) {
 | ||
|                 // 记录错误日志并跳过当前循环
 | ||
|                 Log::error("Error processing rootAccountId {$rootAccountId}: " . $e->getMessage());
 | ||
|                 continue;
 | ||
|             }
 | ||
|             //绑定的授权主体全部账号更新后 将f改成t
 | ||
|             $this->googleOAuthService->updateThirdUserDefault($thirdUser->id, 't');
 | ||
|         }
 | ||
| //        return $this->successResponse($allAccounts);
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
|     //添加某个root广告账号的全部层级账号
 | ||
|     public function addRootCustomersNew($options)
 | ||
|     {
 | ||
|         if (!$options) {
 | ||
|             dump('not found new third user');
 | ||
|             return;
 | ||
|         }
 | ||
|         $refresh_token = $options['refresh_token'];
 | ||
|         $access_token  = $options['access_token'];
 | ||
|         $merchant_id   = $options['merchant_id'];
 | ||
|         $user_id       = $options['user_id'];
 | ||
| //dump($refresh_token,$merchant_id,$access_token,9999999);
 | ||
|         $googleAdsAccounts = $this->getAccountHierarchyForBind($options);
 | ||
| //        dump($googleAdsAccounts, 555);
 | ||
|         // 初始化返回结果数组
 | ||
|         $ad_accounts = [];
 | ||
| 
 | ||
|         //广告主体的profile信息 通过请求api返回
 | ||
|         $googleAccountInfo = $this->googleOAuthService->getGoogleAccountInfo($access_token);
 | ||
| 
 | ||
| //        dump($googleAccountInfo,333);
 | ||
| 
 | ||
|         foreach ($googleAdsAccounts as $login_customer_id => $accounts) {
 | ||
| //            dump($login_customer_id, $accounts,66);
 | ||
|             if (!empty($accounts[$login_customer_id])) {
 | ||
|                 foreach ($accounts[$login_customer_id] as $account) {
 | ||
|                     $data = [
 | ||
|                         'account_id' => $account['account_id'],
 | ||
|                         'account_name' => $account['account_name'],
 | ||
|                         'currency' => $account['currency'],
 | ||
|                         'merchant_id' => $merchant_id,
 | ||
|                         'user_id' => $user_id,
 | ||
|                         'access_token' => $refresh_token,
 | ||
|                         'refresh_token' => $refresh_token,
 | ||
|                         'platform_user_id' => $googleAccountInfo['id'],
 | ||
|                         'platform_user_name' => $googleAccountInfo['name'],
 | ||
|                         'is_unbind' => 't',
 | ||
|                         //ext_info是jsonb  存放 $account['login_customer_id']的键值对
 | ||
|                         'ext_info' => json_encode(['login_customer_id' => $login_customer_id]),
 | ||
|                     ];
 | ||
| //                    dump($data);
 | ||
|                     $this->googleOAuthService->saveThirdUserAdvertiserNew($data, 1);
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
| //            dump($ad_accounts);
 | ||
| //        return $this->successResponse(['ad_accounts' => $ad_accounts, 'total_count' => count($ad_accounts)]);
 | ||
|         //绑定的授权主体全部账号更新后 将f改成t
 | ||
| //        $this->googleOAuthService->updateThirdUserDefault($thirdUser->id, 't');
 | ||
| //        return $this->successResponse($allAccounts);
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
|     //每分钟定时轮询缓存是否有新的广告账号需要绑定-荣洁set缓存
 | ||
|     public function newBindAccount()
 | ||
|     {
 | ||
|         $redisKey = 'bps:ads:new_bind_account'; //$options['token'] 即uuid 例如:f47ac10b-58cc-4372-a567-0e02b2c3d479
 | ||
|         // 获取哈希表所有字段和值
 | ||
|         if (!Redis::exists($redisKey)) {
 | ||
|             dump('no pending uuid');
 | ||
|             return;
 | ||
|         }
 | ||
|         $hashData = Redis::hGetAll($redisKey);
 | ||
|         if (empty($hashData)) {
 | ||
|             dump('no pending bindings accounts');
 | ||
|             return;
 | ||
|         }
 | ||
| 
 | ||
|         foreach ($hashData as $uuid => $bindingStr) {
 | ||
|             // 解析商户ID和账户列表 格式:"merchantId_platform_account1,account2"
 | ||
|             [$merchantId, $platform, $accountsStr] = explode('_', $bindingStr, 3);
 | ||
|             if ((int)$platform !== 2) {
 | ||
|                 continue;
 | ||
|             }
 | ||
|             // 需要实际数据来源
 | ||
|             $bindAccounts = explode(',', $accountsStr);
 | ||
|             foreach ($bindAccounts as $account) {
 | ||
|                 $data = [
 | ||
|                     'merchant_id' => $merchantId, // 分离商户ID
 | ||
|                     'account_id' => $account
 | ||
|                 ];
 | ||
|                 $this->googleOAuthService->queueNew($data);
 | ||
|             }
 | ||
|             // 处理完成后删除哈希字段
 | ||
|             Redis::hDel($redisKey, $uuid);
 | ||
|         }
 | ||
|         return $this->successResponse(['success' => 'new binded accounts queued for initialization.']);
 | ||
|     }
 | ||
| 
 | ||
|     // 没调用 管理用户访问权限
 | ||
|     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);
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * 绑定接口-广告主体下层级账号
 | ||
|      * @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;
 | ||
|             }
 | ||
|         }
 | ||
| //        dump($resourceName,222);
 | ||
|         return $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
 | ||
|         ]);
 | ||
|     }
 | ||
| }
 | 
