From 0abc7a77a25bd562f01686684d9642636ccfa30d Mon Sep 17 00:00:00 2001 From: huangguancheng Date: Wed, 15 Jan 2025 14:20:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=87=E7=AD=BE=E9=A1=B5=E8=A7=92=E6=A0=87?= =?UTF-8?q?=E6=95=B0=E5=AD=97=EF=BC=88Accounts=E3=80=81Campaigns=E3=80=81A?= =?UTF-8?q?d=20Sets=20=E3=80=81Ads=E3=80=81Creatives=EF=BC=89=E6=9B=B4?= =?UTF-8?q?=E6=96=B03=20+=E5=AF=BC=E5=87=BA=E5=B9=BF=E5=91=8A=E7=B3=BB?= =?UTF-8?q?=E5=88=97=E5=88=97=E8=A1=A8=E5=88=B0=20Excel=20=E6=9B=B4?= =?UTF-8?q?=E6=96=B01?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/BpsAdController.php | 91 ++++++++++++++++++++++++--- app/service/AdsInsightService.php | 99 ++++++++++++++++++++++++++---- config/route.php | 8 ++- 3 files changed, 176 insertions(+), 22 deletions(-) diff --git a/app/controller/BpsAdController.php b/app/controller/BpsAdController.php index 00f0ea4..fd59459 100644 --- a/app/controller/BpsAdController.php +++ b/app/controller/BpsAdController.php @@ -53,6 +53,34 @@ class BpsAdController */ private $bpsAdAccountService; + /* + * 返回标签页角标数字接口 + * + */ + public function listAdBadges(Request $request) + { + $options = $request->all(); + $options['jwtClaims'] = $request->jwtClaims; + + // 获取请求参数 +// $startDate = $options['conditions']['startDate'] ?? null; // 开始日期 +// $endDate = $options['conditions']['endDate'] ?? null; // 结束日期 + $accounts = $this->bpsAdAccountService->getAllAdAccounts(['uid' => $options['jwtClaims']['uid']]); + if (empty($accounts)) { + return $this->successResponse(['data' => []], $request); + } + $accountIds = array_unique(array_column($accounts, 'account_id')); + $endDateLastWeek = (int)date('Ymd'); + $startDateLastWeek = (int)date('Ymd', strtotime('-6 days')); +// dump($startDateLastWeek, $endDateLastWeek); +// if ($startDateLastWeek === $startDate && $endDateLastWeek === $endDate) { + $ad_data_count = $this->adsInsightService::getAdCountData($accountIds, $startDateLastWeek, $endDateLastWeek); +// } else { +// $ad_data_count = []; +// } + // 返回结果 + return $this->successResponse($ad_data_count, $request); + } public function listThirdUsers(Request $request) { @@ -97,14 +125,6 @@ class BpsAdController // 获取客户ID数组 $accountIds = array_unique(array_column($accounts, 'account_id')); - $endDateLastWeek = (int)date('Ymd'); - $startDateLastWeek = (int)date('Ymd', strtotime('-6 days')); -// dump($startDateLastWeek, $endDateLastWeek); - if ($startDateLastWeek === $startDate && $endDateLastWeek === $endDate) { - $ad_data_count = $this->adsInsightService::getAdCountData($accountIds,$startDate, $endDate); - } else { - $ad_data_count = []; - } // 调用 Service 层查询广告列表 $result = $this->adsInsightService::getAccountList( @@ -117,7 +137,6 @@ class BpsAdController $endDate, // 结束日期 ); - $result['ad_data_count'] = $ad_data_count; // 返回结果 return $this->successResponse($result, $request); @@ -291,6 +310,60 @@ class BpsAdController // return $this->errorResponse(300,'授权失败'); } + public function exportCampaignsToExcel(Request $request) + { + $options = $request->all(); + $options['jwtClaims'] = $request->jwtClaims; + + // 获取请求参数 + $page = $options['pageNo'] ?? 1; // 页码 + $pageSize = $options['pageSize'] ?? 1000; // 每页数量 + $keyword = $options['conditions']['keyword'] ?? ''; // 关键字搜索 + $platformType = $options['conditions']['platformType'] ?? 0; // 关键字搜索 + $status = $options['conditions']['status'] ?? 0; // 平台类型 + $startDate = $options['conditions']['startDate'] ?? null; // 开始日期 + $endDate = $options['conditions']['endDate'] ?? null; // 结束日期 +// $dateRange = 'Last Week'; // 默认日期范围 + // 根据 platformType 获取广告账户 + if ($platformType === 1) { + if (!$request->refresh_token_facebook) { + return $this->successResponse(['data' => []], $request); + } + $accounts = $this->bpsAdAccountService->getMetaAdAccounts(['refresh_token' => $request->refresh_token_facebook]); + } elseif ($platformType === 2) { + if (!$request->refresh_token_google) { + return $this->successResponse(['data' => []], $request); + } + $accounts = $this->bpsAdAccountService->getGoogleAdAccounts(['refresh_token' => $request->refresh_token_google]); + } elseif ($platformType === 3) { + if (!$request->refresh_token_tiktok) { + return $this->successResponse(['data' => []], $request); + } + $accounts = $this->bpsAdAccountService->getTiktokAdAccounts(['refresh_token' => $request->refresh_token_tiktok]); + } else { + // TODO: 匹配jwt的商户id还是登录用户id + $accounts = $this->bpsAdAccountService->getAllAdAccounts(['uid' => $options['jwtClaims']['uid']]); + } + + if (empty($accounts)) { + return $this->successResponse(['data' => []], $request); + } + + // 获取客户ID数组 + $accountIds = array_column($accounts, 'account_id'); + // 调用 Service 层查询 + return $this->adsInsightService::exportCampaignsToExcel( + $platformType, + $accountIds, // 客户 ID 数组 + $page, // 页码 + $pageSize, // 每页数量 + $keyword, // 关键字 + $startDate, // 开始日期 + $endDate, // 结束日期 + $status + ); + } + public function listAdsets(Request $request) { $options = $request->all(); diff --git a/app/service/AdsInsightService.php b/app/service/AdsInsightService.php index 767e5d4..79b6c91 100644 --- a/app/service/AdsInsightService.php +++ b/app/service/AdsInsightService.php @@ -174,9 +174,7 @@ class AdsInsightService // 动态构建日期条件 $dateCondition = ''; if ($startDate && $endDate) { - $query->leftJoin('bps.bps_ads_insights d', "c.campaign_id = d.ad_campaign_id AND c.platform_type = d.platform AND {$dateCondition}"); $dateCondition = "d.date BETWEEN '{$startDate}' AND '{$endDate}'"; - } else { } $query->leftJoin('bps.bps_ads_insights d', "c.campaign_id = d.ad_campaign_id AND c.platform_type = d.platform AND {$dateCondition}") ->field('c.campaign_id, c.status as status, c.name, c.account_id,c.platform_type, @@ -305,6 +303,81 @@ class AdsInsightService ]; } + /** + * 导出广告系列列表到 Excel + * + * @param int $platformType 平台类型 + * @param array $customerIds 客户ID列表 + * @param int $page 当前页码 + * @param int $pageSize 每页条数 + * @param string $keyword 关键字 + * @param string|null $startDate 开始日期 + * @param string|null $endDate 结束日期 + * @param int $status 广告系列状态 + */ + public static function exportCampaignsToExcel($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null, $status = 0) + { + $campaignsStatus = [ + 0 => 'UNSPECIFIED', // UNSPECIFIED + 1 => 'UNKNOWN', // UNKNOWN + 2 => 'ENABLED', // ENABLED + 3 => 'PAUSED', // PAUSED + 4 => 'REMOVED', // REMOVED + ]; + + // 调用 getCampaignList 获取广告系列数据 + $campaignList = self::getCampaignList($platformType, $customerIds, $page, $pageSize, $keyword, $startDate, $endDate, $status, false); + + if (empty($campaignList['data'])) { + return ['message' => 'No campaign data available for export.']; + } + + // 创建 Spreadsheet 对象 + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + + // 设置表头 + $headers = [ + 'A1' => 'Campaign ID', 'B1' => 'Status', 'C1' => 'Name', + 'D1' => 'Platform', 'E1' => 'Clicks', 'F1' => 'Spend', + 'G1' => 'Impressions', 'H1' => 'Revenue', 'I1' => 'Purchases' + ]; + foreach ($headers as $cell => $header) { + $sheet->setCellValue($cell, $header); + } + + // 填充数据 + $row = 2; + foreach ($campaignList['data'] as $campaign) { +// $sheet->setCellValueExplicit('A' . $row, (string)$campaign['campaign_id'], \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $sheet->setCellValue('A' . $row, $campaign['id']); + $sheet->setCellValue('B' . $row, $campaignsStatus[$campaign['status']]); + $sheet->setCellValue('C' . $row, $campaign['name']); + $sheet->setCellValue('D' . $row, $campaign['platform_type']); + $sheet->setCellValue('E' . $row, $campaign['clicks']); + $sheet->setCellValue('F' . $row, $campaign['spend']); + $sheet->setCellValue('G' . $row, $campaign['impressions']); + $sheet->setCellValue('H' . $row, $campaign['revenue']); + $sheet->setCellValue('I' . $row, $campaign['purchases']); + $row++; + } + + + // 文件名与路径 + $fileName = 'Exported_Campaigns_' . date('Y-m-d_H-i-s') . '.xlsx'; + $filePath = public_path() . '/' . $fileName; + + // 保存 Excel 文件 + $writer = new Xlsx($spreadsheet); + try { + $writer->save($filePath); + return response()->download($filePath, $fileName); + } catch (\Exception $e) { + return ['success' => false, 'message' => $e->getMessage()]; + } + } + + /** * 获取广告组列表 */ @@ -340,13 +413,13 @@ class AdsInsightService $dateCondition = ''; if ($startDate && $endDate) { $dateCondition = "d.date BETWEEN '{$startDate}' AND '{$endDate}'"; - $query->leftJoin('bps.bps_ads_insights d', "s.ad_set_id = d.ad_set_id AND s.platform_type = d.platform AND {$dateCondition}"); + } // 基础查询:广告组和日数据表联接 - - $query->leftJoin('bps.bps_ads_campaign c', 's.campaign_id = c.campaign_id') // 联接广告系列表 - ->field('s.ad_set_id, s.status as status, s.name, s.account_id,s.platform_type,c.name as campaign_name, + $query->leftJoin('bps.bps_ads_insights d', "s.ad_set_id = d.ad_set_id AND s.platform_type = d.platform AND {$dateCondition}") + ->leftJoin('bps.bps_ads_campaign c', 's.campaign_id = c.campaign_id') // 联接广告系列表 + ->field('s.ad_set_id, s.status as status, s.name, s.account_id,s.platform_type,c.name as campaign_name, COALESCE(SUM(d.assisted_purchases), 0) as assisted_purchases, COALESCE(SUM(d.last_clicked_purchases), 0) as last_clicked_purchases, COALESCE(SUM(d.clicks), 0) as clicks, @@ -504,12 +577,13 @@ class AdsInsightService $dateCondition = ''; if ($startDate && $endDate) { $dateCondition = "d.date BETWEEN '{$startDate}' AND '{$endDate}'"; - $query->leftJoin('bps.bps_ads_insights d', "a.advertiser_id = d.account_id AND {$dateCondition}"); + } // 基础查询:广告和日数据表联接 // 其他联表及字段计算 - $query->leftJoin('bps.bps_third_user u', 'a.doc_ = u.id') + $query->leftJoin('bps.bps_ads_insights d', "a.advertiser_id = d.account_id AND {$dateCondition}") + ->leftJoin('bps.bps_third_user u', 'a.doc_ = u.id') ->field('a.advertiser_id, a.advertiser_name,u.third_type, COALESCE(SUM(d.assisted_purchases), 0) as assisted_purchases, COALESCE(SUM(d.last_clicked_purchases), 0) as last_clicked_purchases, @@ -673,12 +747,13 @@ class AdsInsightService $dateCondition = ''; if ($startDate && $endDate) { $dateCondition = "d.date BETWEEN '{$startDate}' AND '{$endDate}'"; - $query->leftJoin('bps.bps_ads_insights d', "a.ad_id = d.ad_id AND a.platform_type = d.platform AND {$dateCondition}"); + } // 基础查询:广告和日数据表联接 - $query->leftJoin('bps.bps_ads_set s', 'a.ad_set_id = s.ad_set_id') // 联接广告组表,获取 ad_set_name - ->field('a.ad_id, a.status as status, a.name, a.account_id,a.platform_type,s.name as ad_set_name, + $query->leftJoin('bps.bps_ads_insights d', "a.ad_id = d.ad_id AND a.platform_type = d.platform AND {$dateCondition}") + ->leftJoin('bps.bps_ads_set s', 'a.ad_set_id = s.ad_set_id') // 联接广告组表,获取 ad_set_name + ->field('a.ad_id, a.status as status, a.name, a.account_id,a.platform_type,s.name as ad_set_name, COALESCE(SUM(d.assisted_purchases), 0) as assisted_purchases, COALESCE(SUM(d.last_clicked_purchases), 0) as last_clicked_purchases, COALESCE(SUM(d.clicks), 0) as clicks, @@ -1108,7 +1183,7 @@ class AdsInsightService if (!empty($customerIds)) { $creativeDataQuery->whereIn('i.account_id', $customerIds); } else { - return $countOnly ? 0 :[ + return $countOnly ? 0 : [ 'data' => [], 'total' => 0, 'statistics' => [], diff --git a/config/route.php b/config/route.php index 70185d3..7224755 100644 --- a/config/route.php +++ b/config/route.php @@ -48,7 +48,7 @@ Route::group('/marketing', function () { Route::group('/campaign', function () { Route::post('/list', [BpsAdController::class, 'listCampaigns']); -// Route::post('/export', [BpsAdController::class, 'exportCampaignsToExcel']); + Route::post('/export', [BpsAdController::class, 'exportCampaignsToExcel']); // Route::group('/status', function () { // Route::post('/update', [BpsAdController::class, 'updateCampaignStatus']); // Route::post('/get', [BpsAdController::class, 'getCampaignStatus']); @@ -74,6 +74,12 @@ Route::group('/marketing', function () { app\middleware\JwtLocal::class, app\middleware\OauthThirdCheck::class, ]); + Route::group('/badge', function () { + Route::post('/list', [BpsAdController::class, 'listAdBadges']); + })->middleware([ + app\middleware\JwtLocal::class, + app\middleware\OauthThirdCheck::class, + ]); Route::group('/creative', function () { Route::post('/list', [BpsAdController::class, 'listCreatives']); Route::post('/chart', [BpsAdController::class, 'listCharts']);