372 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			372 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | ||
| 
 | ||
| namespace app\controller;
 | ||
| 
 | ||
| use app\service\GoogleOAuthService;
 | ||
| use app\service\GoogleAdsAccountService;
 | ||
| use Google\ApiCore\ApiException;
 | ||
| use support\Log;
 | ||
| use support\Request;
 | ||
| use support\Response;
 | ||
| use support\Redis;
 | ||
| use DI\Annotation\Inject;
 | ||
| 
 | ||
| //use app\model\ThirdUserAdvertiser;
 | ||
| 
 | ||
| class CustomerController
 | ||
| {
 | ||
|     // 育才定义 绑定广告账号时的该uuid的广告token  Redis 键名前缀
 | ||
|     const REDIS_KEY_PREFIX = 'bps-goui:third:token:key:';
 | ||
| 
 | ||
|     /**
 | ||
|      * @Inject
 | ||
|      * @var GoogleOAuthService
 | ||
|      */
 | ||
|     private $googleOAuthService;
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * @Inject
 | ||
|      * @var GoogleAdsAccountService
 | ||
|      */
 | ||
|     private $googleAdsAccountService;
 | ||
| 
 | ||
|     /**
 | ||
|      * 作废2025-2-13
 | ||
|      *
 | ||
|      */
 | ||
| //    public function getCustomerList(Request $request)
 | ||
| //    {
 | ||
| //        $thirdUserId = $request->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
 | ||
|         ]);
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
| } | 
