jwt grpc调用

This commit is contained in:
hgc 2025-01-06 14:47:09 +08:00
parent d19edf4fd5
commit 9d6e55988f
7 changed files with 313 additions and 382 deletions

View File

@ -70,7 +70,7 @@ class AdController
$startDate, // 开始日期
$endDate
); // 结束日期);
return $this->successResponse($result);
return $this->successResponse($result, $request);
}
public function listAssets(Request $request)
@ -88,15 +88,13 @@ class AdController
// $customerId = 4060397299;
$customers = $this->googleOAuthService->getGoogleAdCustomers(['refresh_token' => $request->refresh_token]);
$customerIds = array_column($customers, 'customer_id');
// 你可以进一步验证日期格式(可选)
// if ($startDate && !strtotime($startDate)) {
// return response()->json(['error' => 'Invalid start date format'], 400);
// }
// if ($endDate && !strtotime($endDate)) {
// return response()->json(['error' => 'Invalid end date format'], 400);
// }
//dump( $customerIds, // 客户 ID 数组
// $page, // 页码
// $pageSize, // 每页数量
// $keyword, // 关键字
// $dateRange,
// $startDate, // 开始日期
// $endDate);
// 调用 Service 层查询
$result = $this->googleAdsReportService->getAssetConversionData(
$customerIds, // 客户 ID 数组
@ -106,7 +104,7 @@ class AdController
$dateRange,
$startDate, // 开始日期
$endDate);
return $this->successResponse($result);
return $this->successResponse($result, $request);
}
public function listCampaigns(Request $request)
@ -133,7 +131,7 @@ class AdController
$startDate, // 开始日期
$endDate // 结束日期
);
return $this->successResponse($result);
return $this->successResponse($result, $request);
// return $this->errorResponse(300,'授权失败');
}
@ -217,7 +215,7 @@ class AdController
$startDate, // 开始日期
$endDate
);
return $this->successResponse($result);
return $this->successResponse($result, $request);
}
@ -260,7 +258,7 @@ class AdController
if (!$reslut) {
return $this->errorResponse(101, 'Status update failed');
}
return $this->successResponse(['message' => 'Status updated successfully']);
return $this->successResponse(['message' => 'Status updated successfully'], $request);
// } catch (ValidateException $e) {
// return $this->errorResponse(400, $e->getMessage());
// }
@ -334,7 +332,7 @@ class AdController
if (!$result) {
return $this->errorResponse(101, 'Status update failed');
}
return $this->successResponse(['message' => 'Status updated successfully']);
return $this->successResponse(['message' => 'Status updated successfully'], $request);
// } catch (ValidateException $e) {
// return $this->errorResponse(400, $e->getMessage());
// }
@ -367,7 +365,7 @@ class AdController
if (!$result) {
return $this->errorResponse(101, 'Status update failed');
}
return $this->successResponse(['message' => 'Status updated successfully']);
return $this->successResponse(['message' => 'Status updated successfully'], $request);
// } catch (ValidateException $e) {
// return $this->errorResponse(400, $e->getMessage());
// }
@ -375,8 +373,16 @@ class AdController
// 可以加入一些公共方法
protected function successResponse($data): Response
protected function successResponse($data, Request $request): Response
{
if ($request->jwtNewToken) {
return new Response(200,
[
'Content-Type' => 'application/json',
'X-New-Token' => $request->jwtNewToken
],
json_encode($data, JSON_UNESCAPED_UNICODE));
} else {
return Json([
'code' => 0,
'msg' => 'ok',
@ -384,6 +390,9 @@ class AdController
]);
}
}
protected function errorResponse($code, $message, $data = []): Response
{
return Json([

View File

@ -28,7 +28,7 @@ class OAuthController
$authUrl = $this->googleOAuthService->getAuthUrl($state);
return $this->successResponse([
'url' => $authUrl,
]);
],$request);
}
@ -62,7 +62,7 @@ class OAuthController
// } else {
// return $this->errorResponse(300, 'Invalid state parameter');
// }
return $this->successResponse($tokens);
return $this->successResponse($tokens,$request);
}
@ -114,7 +114,7 @@ class OAuthController
$googleOAuthService = new GoogleOAuthService();
$googleOAuthService->revokeToken($accessToken, $thirdUser->id);
return $this->successResponse(['deleted' => 'success']);
return $this->successResponse(['deleted' => 'success'],$request);
}
@ -138,29 +138,7 @@ class OAuthController
public function testRefreshToken(Request $request)
{
// 接建立socket连到内部推送端口
$client = stream_socket_client('tcp://192.168.21.27:22101', $errorCode, $errorMessage);
if (false === $client) {
throw new \Exception('rpc failed to connect: ' . $errorMessage);
}
$rpc_request = [
'class' => 'Auth',
'method' => 'ValidateJwtToken',
'args' => [
[
'uid' => 2023,
'username' => 'Tinywan',
]
]
];
// 发送数据注意5678端口是Text协议的端口Text协议需要在数据末尾加上换行符
fwrite($client, json_encode($rpc_request) . "\n");
// 读取推送结果
$result = fgets($client, 10240000);
// 解析JSON字符串
$result = json_decode($result, true);
dump($result);
return $this->successResponse($result);
return $this->successResponse([],$request);
//发布事件
// $dayBeforeYesterdayStart = date('Y-m-d', strtotime('-2 day'));
@ -173,10 +151,10 @@ class OAuthController
// Event::emit(GoogleAdsGroups::type, []);
// dump(date('Y-m-d H:i:s') . '更新' . GoogleAdsAds::type . '开始');
// Event::emit(GoogleAdsAdMaterials::type, []);
dump(date('Y-m-d H:i:s') . '更新' . GoogleAdsMaterials::type . '开始');
Event::emit(GoogleAdsMaterials::type, []);
// dump(date('Y-m-d H:i:s') . '更新' . GoogleAdsMaterials::type . '开始');
// Event::emit(GoogleAdsMaterials::type, []);
return $this->successResponse(['data' => []]);
// return $this->successResponse(['data' => []]);
// $customers = $this->googleOAuthService->getGoogleAdCustomers([]);
@ -205,38 +183,47 @@ class OAuthController
// 使用 ThinkDb 进行联表查询
// $advertiserId = 'your-advertiser-id'; // 假设你已经获得了广告商ID
$requestData = $request->all(); // 获取请求数据
$customerId = $requestData['customer_id'];
// 通过 advertiser_id 查询 ThirdUserAdvertiser联表查询 ThirdUser 数据
$userAdvertiser = ThirdUserAdvertiser::with('googleUser') // 联表查询 user 关联
->where('advertiser_id', $customerId) // 根据 advertiser_id 查询
->find(); // 获取第一个结果
// $requestData = $request->all(); // 获取请求数据
// $customerId = $requestData['customer_id'];
//
// // 通过 advertiser_id 查询 ThirdUserAdvertiser联表查询 ThirdUser 数据
// $userAdvertiser = ThirdUserAdvertiser::with('googleUser') // 联表查询 user 关联
// ->where('advertiser_id', $customerId) // 根据 advertiser_id 查询
// ->find(); // 获取第一个结果
// 如果找到广告主数据
if ($userAdvertiser && $userAdvertiser->googleUser) {
// 获取关联用户的 access_token
$accessToken = $userAdvertiser->googleUser->access_token;
// dump($accessToken); // 打印 access_token
return $this->successResponse($accessToken); // 返回 access_token
} else {
// 如果没有找到广告主或关联的用户,返回错误信息
// dump('未找到该广告主或关联的用户');
return $this->errorResponse('101', '未找到该广告主或关联的用户');
}
// if ($userAdvertiser && $userAdvertiser->googleUser) {
// // 获取关联用户的 access_token
// $accessToken = $userAdvertiser->googleUser->access_token;
//// dump($accessToken); // 打印 access_token
// return $this->successResponse($accessToken); // 返回 access_token
// } else {
// // 如果没有找到广告主或关联的用户,返回错误信息
//// dump('未找到该广告主或关联的用户');
// return $this->errorResponse('101', '未找到该广告主或关联的用户');
// }
}
// 可以加入一些公共方法
protected function successResponse($data): Response
protected function successResponse($data,Request $request): Response
{
if ($request->jwtNewToken) {
return new Response(200,
[
'Content-Type' => 'application/json',
'X-New-Token' => $request->jwtNewToken
],
json_encode($data, JSON_UNESCAPED_UNICODE));
} else {
return Json([
'code' => 0,
'msg' => 'ok',
'data' => $data,
]);
}
}
protected function errorResponse($code, $message, $data = []): Response
{

View File

@ -2,78 +2,134 @@
namespace app\middleware;
use Webman\MiddlewareInterface;
use Webman\Http\Request;
use Webman\Http\Response;
use Firebase\JWT\JWT as FJWT;
use Firebase\JWT\Key;
use Exception;
use Webman\MiddlewareInterface;
use GRPC\Auth\AuthClient;
use GRPC\Auth\ValidateJwtTokenReq;
use GRPC\Auth\JwtVerifyResult;
class Jwt implements MiddlewareInterface
{
// 签名密钥
private const SIGNING_KEY = '83OP5jf43875jK7';
protected $authClient;
public function __construct()
{
// 初始化 AuthClient
$host = "192.168.21.27:22101"; // 替换为你的 Auth 服务地址
$this->authClient = new AuthClient($host);
}
public function process(Request $request, callable $handler): Response
{
// 获取 Authorization 头
$authorization = $request->header('Authorization', '');
if (empty($authorization) || strpos($authorization, 'Bearer ') !== 0) {
// 从请求头中获取 JWT token
$jwtToken = $request->header('Authorization');
if (!$jwtToken) {
return Json([
'code' => 1,
'msg' => '缺少 Authorization 头或格式无效',
'msg' => 'Authorization token is missing',
'data' => []
]);
}
// 提取 JWT token
$jwtToken = substr($authorization, 7);
try {
// 使用 firebase/php-jwt 解码并验证 JWT
// $decoded = FJWT::decode($jwtToken, new Key(self::SIGNING_KEY, 'HS512'), $headers = new stdClass()); // 使用 HMAC-SHA512 算法进行验证
$decoded = FJWT::decode($jwtToken, new Key(self::SIGNING_KEY, 'HS512'));
// 将解码后的数据(即 claims存入请求对象后续可以访问
$request->jwtClaims = (array)$decoded;
// 验证 JWT Token
// dump((array)$decoded);
// return Json([
// 'code' => 0,
// 'msg' => 'JWT 验证成功',
// 'data' => []
// ]);
// 继续处理请求
return $handler($request);
} catch (Exception $e) {
return Json([
'code' => 1,
'msg' => $e->getMessage(),
'data' => []
]);
// return response(['code' => 1, 'msg' => 'JWT 验证失败: ' . $e->getMessage()], 200);
}
// 去除 Bearer 前缀
if (strpos($jwtToken, 'Bearer ') === 0) {
$jwtToken = substr($jwtToken, 7);
}
// try {
// 创建 GRPC 请求
// dump($jwtToken);
$grpcRequest = new ValidateJwtTokenReq();
$grpcRequest->setJwtToken($jwtToken);
// 调用 GRPC 服务
// list($response, $status) = $this->authClient->ValidateJwtToken($grpcRequest);
$responseAuth = $this->authClient->ValidateJwtToken($grpcRequest);
private function getErrorMessage($result)
{
// 检查验证结果
// 获取验证结果
$result = $responseAuth->getResult();
// 根据验证结果返回不同的消息
switch ($result) {
case 'JWT_VERIFY_BAD_FORMAT':
return '无效的 token 格式';
case 'JWT_VERIFY_SIGN_FAILED':
return 'token 签名无效';
case 'JWT_VERIFY_EXPIRED':
return 'token 已过期';
case 'JWT_VERIFY_REVOKED':
return 'token 已被撤销';
case 'JWT_VERSION_LOW':
return 'token 版本过低';
case JwtVerifyResult::JWT_VERIFY_OK:
// Token 验证成功,继续执行下层逻辑
break;
case JwtVerifyResult::JWT_VERIFY_BAD_FORMAT:
return Json([
'code' => 1,
'msg' => 'Invalid token format',
'data' => []
]);
case JwtVerifyResult::JWT_VERIFY_SIGN_FAILED:
return Json([
'code' => 1,
'msg' => 'Token signature is invalid',
'data' => []
]);
case JwtVerifyResult::JWT_VERIFY_EXPIRED:
return Json([
'code' => 1,
'msg' => 'Token has expired',
'data' => []
]);
case JwtVerifyResult::JWT_VERIFY_REVOKED:
return Json([
'code' => 1,
'msg' => 'Token has been revoked',
'data' => []
]);
case JwtVerifyResult::JWT_VERSION_LOW:
return Json([
'code' => 1,
'msg' => 'Token version is too low',
'data' => []
]);
default:
return '未知错误';
return Json([
'code' => 1,
'msg' => 'Unknown token verification error',
'data' => []
]);
}
// 将解析的 claims 数据传递给下层业务逻辑
$claims = $responseAuth->getClaims();
if ($claims) {
// 获取 uid 和 merchant_id
$uid = $claims->getUid();
$merchantId = $claims->getMerchantId();
// dump("UID: " . $uid); // 打印 uid
// dump("Merchant ID: " . $merchantId); // 打印 merchant_id
// 将 claims 数据附加到请求对象中,供后续使用
$request->jwtClaims = [
'uid' => $uid,
'merchant_id' => $merchantId
];
}
// 检查是否存在新 token
$newToken = $responseAuth->getNewToken();
if ($newToken) {
$request->jwtNewToken = $newToken;
// response()->withHeader('X-New-Token',$newToken);
}
// 如果验证通过,则继续处理请求
return $handler($request);
// } catch (\Exception $e) {
// return new Response(500, [], json_encode(['error' => 'Internal server error']));
// }
}
}

View File

@ -0,0 +1,79 @@
<?php
namespace app\middleware;
use Webman\MiddlewareInterface;
use Webman\Http\Request;
use Webman\Http\Response;
use Firebase\JWT\JWT as FJWT;
use Firebase\JWT\Key;
use Exception;
class JwtLocal implements MiddlewareInterface
{
// 签名密钥
private const SIGNING_KEY = '83OP5jf43875jK7';
public function process(Request $request, callable $handler): Response
{
// 获取 Authorization 头
$authorization = $request->header('Authorization', '');
if (empty($authorization) || strpos($authorization, 'Bearer ') !== 0) {
return Json([
'code' => 1,
'msg' => '缺少 Authorization 头或格式无效',
'data' => []
]);
}
// 提取 JWT token
$jwtToken = substr($authorization, 7);
try {
// 使用 firebase/php-jwt 解码并验证 JWT
// $decoded = FJWT::decode($jwtToken, new Key(self::SIGNING_KEY, 'HS512'), $headers = new stdClass()); // 使用 HMAC-SHA512 算法进行验证
$decoded = FJWT::decode($jwtToken, new Key(self::SIGNING_KEY, 'HS512'));
// 将解码后的数据(即 claims存入请求对象后续可以访问
$request->jwtClaims = (array)$decoded;
// 验证 JWT Token
// dump((array)$decoded);
// return Json([
// 'code' => 0,
// 'msg' => 'JWT 验证成功',
// 'data' => []
// ]);
// 继续处理请求
return $handler($request);
} catch (Exception $e) {
return Json([
'code' => 1,
'msg' => $e->getMessage(),
'data' => []
]);
// return response(['code' => 1, 'msg' => 'JWT 验证失败: ' . $e->getMessage()], 200);
}
}
private function getErrorMessage($result)
{
switch ($result) {
case 'JWT_VERIFY_BAD_FORMAT':
return '无效的 token 格式';
case 'JWT_VERIFY_SIGN_FAILED':
return 'token 签名无效';
case 'JWT_VERIFY_EXPIRED':
return 'token 已过期';
case 'JWT_VERIFY_REVOKED':
return 'token 已被撤销';
case 'JWT_VERSION_LOW':
return 'token 版本过低';
default:
return '未知错误';
}
}
}

View File

@ -1,88 +0,0 @@
<?php
namespace app\middleware;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;
use GRPC\Auth\AuthClient;
use GRPC\Auth\ValidateJwtTokenReq;
use GRPC\Auth\JwtVerifyResult;
class JwtRpc implements MiddlewareInterface
{
protected $authClient;
public function __construct()
{
// 初始化 AuthClient
$host = "192.168.21.27:22101"; // 替换为你的 Auth 服务地址
$this->authClient = new AuthClient($host);
}
public function process(Request $request, callable $handler): Response
{
// 从请求头中获取 JWT token
$jwtToken = $request->header('Authorization');
if (!$jwtToken) {
return response()->json(['error' => 'Authorization token is missing'], 401);
}
// 去除 Bearer 前缀
if (strpos($jwtToken, 'Bearer ') === 0) {
$jwtToken = substr($jwtToken, 7);
}
try {
// 创建 GRPC 请求
dump($jwtToken);
$grpcRequest = new ValidateJwtTokenReq();
$grpcRequest->setJwtToken($jwtToken);
// 调用 GRPC 服务
list($response, $status) = $this->authClient->ValidateJwtToken($grpcRequest)->wait();
if ($status->code !== \Grpc\STATUS_OK) {
return Json([
'code' => 1,
'msg' => 'GRPC service error',
'data' => []
]);
}
// 检查验证结果
if ($response->getResult() !== JwtVerifyResult::JWT_VERIFY_OK) {
return Json([
'code' => 1,
'msg' => 'Invalid token',
'data' => []
]);
}
// 将解析的 claims 数据传递给下层业务逻辑
$claims = $response->getClaims();
dump($claims);
return Json([
'code' => 0,
'msg' => 'test token well',
'data' => []
]);
$request->jwtClaims = $claims;
// if ($result['is_valid']) {
// dump("JWT 验证成功: " . json_encode($result['claims']));
// } else {
// dump("JWT 验证失败: " . $result['error']);
// }
// if (!$isValid) {
// return response()->json(['error' => 'Invalid token'], 401);
// }
// 如果验证通过,则继续处理请求
return $handler($request);
} catch (\Exception $e) {
return new Response(500, [], json_encode(['error' => 'Internal server error']));
}
}
}

View File

@ -16,6 +16,13 @@ use think\model\Collection;
class GoogleAdsReportService
{
// 状态映射数组
private static $statusMapping = [
2 => 'ENABLE', // 2 代表广告已启用
3 => 'PAUSED', // 3 代表广告待审核等状态
// 其他状态可以继续添加
];
/**
* 获取广告列表
*/
@ -106,7 +113,7 @@ class GoogleAdsReportService
'revenue' => '-',
'roas' => '-',
'profit' => '-',
'spend' => number_format(array_sum(array_column($allAds, 'spend')),2) ?: '0.00',
'spend' => '$' . number_format(array_sum(array_column($allAds, 'spend')), 2) ?: '$0.00',
'be_roas' => '-'
];
// 获取查询结果
@ -155,11 +162,11 @@ class GoogleAdsReportService
'revenue' => $item['revenue'] == -1 ? '-' : $item['revenue'],
'roas' => $item['roas'] == -1 ? '-' : $item['roas'],
'profit' => $item['profit'] == -1 ? '-' : $item['profit'],
'spend' => number_format($item['spend'], 2),
'spend' => '$' . number_format($item['spend'], 2),
'campaign_name' => $item['campaign_name'],
'ad_set_name' => $item['ad_group_name'], // Assuming ad_group_name as ad_set_name
'delivery' => $item['ad_status'],
'delivery_status' => '-', // Assuming active as '活动'
'delivery' => self::$statusMapping[$item['ad_status']],
'delivery_status' => $item['ad_status'], // Assuming active as '活动'
'be_roas' => $item['be_roas'] == -1 ? '-' : $item['be_roas'],
'image_url' => $assetUrl, // Add logic to populate image URLs if available
];
@ -200,7 +207,7 @@ class GoogleAdsReportService
* @param string $dateRange
* @return void
*/
public static function exportAdListToExcel($customerIds,$keyword, $dateRange, $startDate = null, $endDate = null)
public static function exportAdListToExcel($customerIds, $keyword, $dateRange, $startDate = null, $endDate = null)
{
if (empty($customerIds)) {
return [];
@ -412,7 +419,7 @@ class GoogleAdsReportService
$statistics = [
'results' => '-',
'reach' => array_sum(array_column($allCampaigns, 'reach')) ?: 0,
'spend' => number_format(array_sum(array_column($allCampaigns, 'spend')),2) ?: '0.00',
'spend' => '$' . number_format(array_sum(array_column($allCampaigns, 'spend')), 2) ?: '$0.00',
'revenue' => '-',
'roas' => '-',
'profit' => '-',
@ -434,9 +441,9 @@ class GoogleAdsReportService
'revenue' => $item['revenue'] == -1 ? '-' : $item['revenue'],
'roas' => $item['roas'] == -1 ? '-' : $item['roas'],
'profit' => $item['profit'] == -1 ? '-' : $item['profit'],
'spend' => number_format($item['spend'], 2),
'delivery' => $item['campaign_status'],
'delivery_status' => '-', // 默认状态
'spend' => '$' . number_format($item['spend'], 2),
'delivery' => self::$statusMapping[$item['campaign_status']],
'delivery_status' => $item['campaign_status'], // 默认状态
'be_roas' => $item['be_roas'] == -1 ? '-' : $item['be_roas'],
];
}, $campaigns->items());
@ -459,75 +466,6 @@ class GoogleAdsReportService
}
/**
* 获取广告系列列表
*/
public static function getCampaignList1111($page, $pageSize, $keyword, $dateRange, $startDate = null, $endDate = null)
{
// 动态构建日期条件
$dateCondition = '';
if ($startDate && $endDate) {
$dateCondition = "d.date BETWEEN '{$startDate}' AND '{$endDate}'";
} else {
switch ($dateRange) {
case 'Today':
$dateCondition = "d.date = '" . date('Y-m-d') . "'";
break;
case 'Yesterday':
$dateCondition = "d.date = '" . date('Y-m-d', strtotime('-1 day')) . "'";
break;
case 'Last Week':
$dateCondition = "d.date >= ' " . date('Y-m-d', strtotime('-1 week')) . "'";
break;
case 'Last Month':
$dateCondition = "d.date >= '" . date('Y-m-d', strtotime('-1 month')) . "'";
break;
case 'Last Year':
$dateCondition = "d.date >= '" . date('Y-m-d', strtotime('-1 year')) . "'";
break;
default:
$dateCondition = "1=1"; // 无日期限制,默认条件始终为真
break;
}
}
// 基础查询:广告活动和日数据表联接
$query = Campaign::alias('c')
->leftJoin('bps.bps_google_ad_day_data d', "c.campaign_id = d.campaign_id AND {$dateCondition}") // 将日期条件加入到 ON 子句中
->field('c.campaign_id, c.status as campaign_status, c.campaign_name, c.customer_id,
COALESCE(SUM(d.clicks), -1) as clicks,
COALESCE(SUM(d.cost_micros) / 1000000, -1) as spend,
COALESCE(SUM(d.conversions), -1) as results,
COALESCE(SUM(d.conversions_value), -1) as conversions_value,
COALESCE(SUM(d.impressions), -1) as reach,
-1 as roas, -1 as be_roas, -1 as revenue, -1 as profit, -1 as delivery')
->group('c.campaign_id, c.status, c.customer_id, c.campaign_name')
->where(function ($query) use ($keyword) {
if ($keyword) {
$query->where('c.campaign_name', 'like', '%' . $keyword . '%');
}
});
// 获取分页数据
$campaigns = $query->paginate($pageSize, false, ['page' => $page]);
// 确保转换为数值
$result = array_map(function ($item) {
$item['spend'] = (float)$item['spend'];
$item['conversions_value'] = (float)$item['conversions_value'];
return $item;
}, $campaigns->items());
// 返回分页和总数信息
return [
'data' => $campaigns->items(),
'total' => $campaigns->total(),
'current_page' => $campaigns->currentPage(),
'last_page' => $campaigns->lastPage(),
];
}
/**
* 导出广告系列数据到 Excel
*
@ -535,9 +473,9 @@ class GoogleAdsReportService
* @param string $dateRange
* @return void
*/
public function exportCampaignsToExcel($customerIds,$keyword, $dateRange, $startDate = null, $endDate = null)
public function exportCampaignsToExcel($customerIds, $keyword, $dateRange, $startDate = null, $endDate = null)
{
if(empty($customerIds)){
if (empty($customerIds)) {
return [];
}
@ -732,7 +670,7 @@ class GoogleAdsReportService
$statistics = [
'results' => '-',
'reach' => array_sum(array_column($allAdGroups, 'reach')) ?: 0,
'spend' => number_format(array_sum(array_column($allAdGroups, 'spend')),2)?: '0.00',
'spend' => '$' . number_format(array_sum(array_column($allAdGroups, 'spend')), 2) ?: '$0.00',
'revenue' => '-',
'roas' => '-',
'profit' => '-',
@ -749,10 +687,12 @@ class GoogleAdsReportService
'customer_id' => $item['customer_id'],
'name' => $item['ad_group_name'] ?: '-',
'status' => $item['ad_group_status'],
'delivery' => self::$statusMapping[$item['ad_group_status']],
'delivery_status' => $item['ad_group_status'], // Assuming active as '活动'
'campaign_name' => $item['campaign_name'],
'results' => $item['results'],
'reach' => $item['reach'],
'spend' => number_format($item['spend'], 2),
'spend' => '$' . number_format($item['spend'], 2),
'revenue' => $item['revenue'] == -1 ? '-' : $item['revenue'],
'roas' => $item['roas'] == -1 ? '-' : $item['roas'],
'profit' => $item['profit'] == -1 ? '-' : $item['profit'],
@ -779,81 +719,12 @@ class GoogleAdsReportService
}
/**
* 获取广告系列列表
*/
public static function getAdGroupList1111($page, $pageSize, $keyword, $dateRange, $startDate = null, $endDate = null)
{
// 动态构建日期条件
$dateCondition = '';
if ($startDate && $endDate) {
$dateCondition = "d.date BETWEEN '{$startDate}' AND '{$endDate}'";
} else {
switch ($dateRange) {
case 'Today':
$dateCondition = "d.date = '" . date('Y-m-d') . "'";
break;
case 'Yesterday':
$dateCondition = "d.date = '" . date('Y-m-d', strtotime('-1 day')) . "'";
break;
case 'Last Week':
$dateCondition = "d.date >= '" . date('Y-m-d', strtotime('-1 week')) . "'";
break;
case 'Last Month':
$dateCondition = "d.date >= '" . date('Y-m-d', strtotime('-1 month')) . "'";
break;
case 'Last Year':
$dateCondition = "d.date >= '" . date('Y-m-d', strtotime('-1 year')) . "'";
break;
default:
$dateCondition = "1=1"; // 默认无日期限制
break;
}
}
// 初始化查询
$query = AdGroup::alias('ag')
->leftJoin("bps.bps_google_ad_day_data d", "ag.ad_group_id = d.ad_group_id AND {$dateCondition}") // 日期条件放入 ON 子句
->leftJoin("bps.bps_google_ads_campaign c", "ag.campaign_id = c.campaign_id") // 关联广告系列表
->field('ag.ad_group_id, ag.ad_group_name, ag.status as ad_group_status, ag.campaign_id, c.campaign_name, ag.customer_id,
COALESCE(SUM(d.clicks), -1) as clicks,
COALESCE(SUM(d.cost_micros) / 1000000, -1) as spend,
COALESCE(SUM(d.conversions), -1) as results,
COALESCE(SUM(d.conversions_value), -1) as conversions_value,
COALESCE(SUM(d.impressions), -1) as reach,
-1 as roas, -1 as be_roas, -1 as revenue, -1 as profit, -1 as delivery')
->group('ag.ad_group_id, ag.ad_group_name, ag.status, ag.campaign_id, c.campaign_name, ag.customer_id')
->where(function ($query) use ($keyword) {
if ($keyword) {
$query->where('ag.ad_group_name', 'like', '%' . $keyword . '%');
}
});
// 获取分页数据
$adGroups = $query->paginate($pageSize, false, ['page' => $page]);
// 确保转换为数值
$result = array_map(function ($item) {
$item['spend'] = (float)$item['spend'];
$item['conversions_value'] = (float)$item['conversions_value'];
return $item;
}, $adGroups->items());
// 返回分页和总数信息
return [
'data' => $adGroups->items(),
'total' => $adGroups->total(),
'current_page' => $adGroups->currentPage(),
'last_page' => $adGroups->lastPage(),
];
}
/**
* 将广告组数据导出到 Excel 文件
*/
public function exportAdGroupsToExcel($customerIds,$keyword = '', $dateRange = 'Today', $startDate = null, $endDate = null)
public function exportAdGroupsToExcel($customerIds, $keyword = '', $dateRange = 'Today', $startDate = null, $endDate = null)
{
if(empty($customerIds)){
if (empty($customerIds)) {
return [];
}
// 动态构建日期条件
@ -1020,8 +891,14 @@ class GoogleAdsReportService
'data' => [],
'chat_1_data' => [], // 返回按月汇总的 chat_data
'total' => 0,
'current_page' => 1,
'last_page' => 1,
'pagination' => [
'startIndex' => 0,
'maxResults' => $pageSize,
'count' => 0,
'pageNo' => 1,
'pageSize' => $pageSize,
'pages' => 1
]
];
}
@ -1207,7 +1084,7 @@ class GoogleAdsReportService
'creative' => $data['asset_name'],
'creative_type' => $data['asset_type'],
'creative_url' => $data['asset_url'],
'spend' => number_format($data['total_spend'], 2),
'spend' => '$' . number_format($data['total_spend'], 2),
'purchase_value' => '-',
'roas' => number_format($roas, 2) . '%',
'cpa' => '-',
@ -1228,7 +1105,7 @@ class GoogleAdsReportService
'video_plays_75_rate' => '-',
'video_plays_100_rate' => '-',
'hold_rate' => '-',
'total_conversions_value' => number_format($data['total_conversions_value'], 2),
'total_conversions_value' => '$' . number_format($data['total_conversions_value'], 2),
'total_conversions' => $data['total_conversions'],
'total_impressions' => $data['total_impressions'],
'ad_count' => count($data['ad']),
@ -1269,15 +1146,26 @@ class GoogleAdsReportService
$chat_data[$month]['roas'] = number_format($chat_data[$month]['roas'], 2) . '%';
}
// 返回分页数据
$totalItems = count($assetSummaryData);
$totalPages = ceil($totalItems / $pageSize);
$startIndex = ($page - 1) * $pageSize;
// 截取返回的数据
// $pagedData = array_slice($assetSummaryData, $startIndex, $pageSize);
$resultDataPaginated = array_slice($resultData, ($page - 1) * $pageSize, $pageSize);
return [
'data' => $resultDataPaginated,
'pagination' => [
'startIndex' => $startIndex,
'maxResults' => $pageSize,
'count' => $totalItems,
'pageNo' => $page,
'pageSize' => $pageSize,
'pages' => $totalPages
],
'chat_1_data' => array_values($chat_data), // 返回按月汇总的 chat_data
'total' => count($resultData),
'current_page' => (int)$page,
'last_page' => ceil(count($resultData) / $pageSize),
'data' => $resultDataPaginated
];
}

View File

@ -65,7 +65,7 @@ class AuthClient extends BaseStub
list($response, $status) = $unaryCall->wait();
// 调试:输出 GRPC 状态码
dump($status);
// dump('2222',$response->getResult(),$response->getClaims(),$status);
// 检查请求是否成功
if ($status->code !== \Grpc\STATUS_OK) {