574 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			574 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | ||
| 
 | ||
| namespace app\service;
 | ||
| 
 | ||
| use app\model\Ad;
 | ||
| use app\model\DayData;
 | ||
| use app\model\Campaign;
 | ||
| use app\model\AdGroup;
 | ||
| use PhpOffice\PhpSpreadsheet\Spreadsheet;
 | ||
| use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
 | ||
| use think\db\exception\DbException;
 | ||
| use think\facade\Db;
 | ||
| use think\model\Collection;
 | ||
| 
 | ||
| class GoogleAdsReportService
 | ||
| {
 | ||
|     /**
 | ||
|      * 获取广告列表
 | ||
|      */
 | ||
|     public static function getAdList($page, $pageSize, $keyword, $dateRange, $startDate = null, $endDate = null)
 | ||
|     {
 | ||
|         // 基础查询:广告表和日数据表联接
 | ||
|         $query = Ad::alias('a')
 | ||
|             ->leftJoin('bps.bps_google_ads_ad_group g', 'a.ad_group_id = g.ad_group_id')  // 关联广告组表
 | ||
|             ->leftJoin('bps.bps_google_ads_campaign c', 'a.campaign_id = c.campaign_id')  // 关联广告系列表
 | ||
|             ->leftJoin('bps.bps_google_ad_day_data d', 'a.ad_id = d.ad_id')
 | ||
|             ->field('a.ad_id, -1 as ad_name, a.status as ad_status, a.customer_id,a.ad_group_id, g.ad_group_name, a.campaign_id,c.campaign_name,
 | ||
|                     SUM(d.clicks) as clicks, SUM(d.cost_micros) / 1000000 as spend,
 | ||
|                     SUM(d.conversions) as results, SUM(d.conversions_value) as conversions_value, 
 | ||
|                     SUM(d.impressions) as reach,-1 as roas,-1 as be_roas,-1 as revenue, -1 as profit, -1 as delivery')
 | ||
|             ->group('a.ad_id, a.ad_name, a.status, a.customer_id, a.ad_group_id, g.ad_group_name, a.campaign_id, c.campaign_name') // 确保所有字段都在 group by 中
 | ||
|             ->where(function ($query) use ($keyword) {
 | ||
|                 if ($keyword) {
 | ||
|                     $query->where('a.ad_name', 'like', '%' . $keyword . '%');
 | ||
|                 }
 | ||
|             });
 | ||
| 
 | ||
|         // 如果提供了 startDate 和 endDate,则根据范围查询
 | ||
|         if ($startDate && $endDate) {
 | ||
|             $query->whereBetween('d.date', [$startDate, $endDate]);
 | ||
|         } else {
 | ||
|             // 根据日期维度添加聚合条件
 | ||
|             switch ($dateRange) {
 | ||
|                 case 'Today':
 | ||
|                     $query->where('d.date', '=', date('Y-m-d'));
 | ||
|                     break;
 | ||
|                 case 'Yesterday':
 | ||
|                     $query->where('d.date', '=', date('Y-m-d', strtotime('-1 day')));
 | ||
|                     break;
 | ||
|                 case 'Last Week':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 week')));
 | ||
|                     break;
 | ||
|                 case 'Last Month':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 month')));
 | ||
|                     break;
 | ||
|                 case 'Last Year':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 year')));
 | ||
|                     break;
 | ||
|                 default:
 | ||
|                     break;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 获取分页数据
 | ||
|         $ads = $query->paginate($pageSize, false, ['page' => $page]);
 | ||
| 
 | ||
|         // 返回分页和总数信息
 | ||
|         return [
 | ||
|             'data' => $ads->items(),
 | ||
|             'total' => $ads->total(),
 | ||
|             'current_page' => $ads->currentPage(),
 | ||
|             'last_page' => $ads->lastPage(),
 | ||
|         ];
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 导出广告列表到 Excel
 | ||
|      *
 | ||
|      * @param string $keyword
 | ||
|      * @param string $dateRange
 | ||
|      * @return void
 | ||
|      */
 | ||
|     public static function exportAdListToExcel($keyword, $dateRange, $startDate = null, $endDate = null)
 | ||
|     {
 | ||
|         // 获取所有的广告数据
 | ||
|         $query = Ad::alias('a')
 | ||
|             ->leftJoin('bps.bps_google_ads_ad_group g', 'a.ad_group_id = g.ad_group_id')  // 关联广告组表
 | ||
|             ->leftJoin('bps.bps_google_ads_campaign c', 'a.campaign_id = c.campaign_id')  // 关联广告系列表
 | ||
|             ->leftJoin('bps.bps_google_ad_day_data d', 'a.ad_id = d.ad_id')
 | ||
|             ->field('a.ad_id, -1 as ad_name, a.status as ad_status, a.customer_id,a.ad_group_id, g.ad_group_name, a.campaign_id,c.campaign_name,
 | ||
|                     SUM(d.clicks) as clicks, SUM(d.cost_micros) / 1000000 as spend,
 | ||
|                     SUM(d.conversions) as results, SUM(d.conversions_value) as conversions_value, 
 | ||
|                     SUM(d.impressions) as reach,-1 as roas,-1 as be_roas,-1 as revenue, -1 as profit, -1 as delivery')
 | ||
|             ->group('a.ad_id, a.ad_name, a.status, a.customer_id, a.ad_group_id, g.ad_group_name, a.campaign_id, c.campaign_name') // 确保所有字段都在 group by 中
 | ||
|             ->where(function ($query) use ($keyword) {
 | ||
|                 if ($keyword) {
 | ||
|                     $query->where('a.ad_name', 'like', '%' . $keyword . '%');
 | ||
|                 }
 | ||
|             });
 | ||
| 
 | ||
|         // 如果提供了 startDate 和 endDate,则根据范围查询
 | ||
|         if ($startDate && $endDate) {
 | ||
|             $query->whereBetween('d.date', [$startDate, $endDate]);
 | ||
|             $dateRange = $startDate. 'to'. $endDate;
 | ||
|         } else {
 | ||
|             // 根据日期维度添加聚合条件
 | ||
|             switch ($dateRange) {
 | ||
|                 case 'Today':
 | ||
|                     $query->where('d.date', '=', date('Y-m-d'));
 | ||
|                     break;
 | ||
|                 case 'Yesterday':
 | ||
|                     $query->where('d.date', '=', date('Y-m-d', strtotime('-1 day')));
 | ||
|                     break;
 | ||
|                 case 'Last Week':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 week')));
 | ||
|                     break;
 | ||
|                 case 'Last Month':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 month')));
 | ||
|                     break;
 | ||
|                 case 'Last Year':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 year')));
 | ||
|                     break;
 | ||
|                 default:
 | ||
|                     break;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 获取所有广告数据
 | ||
|         $ads = $query->select();
 | ||
| 
 | ||
| 
 | ||
|         // 创建一个新的 Spreadsheet 对象
 | ||
|         $spreadsheet = new Spreadsheet();
 | ||
|         $sheet       = $spreadsheet->getActiveSheet();
 | ||
| 
 | ||
|         $ad_status = [
 | ||
|             0 => 'UNSPECIFIED',
 | ||
|             1 => 'UNKNOWN',  // UNKNOW
 | ||
|             2 => 'ENABLED',  // ENABLED
 | ||
|             3 => 'PAUSED',  // PAUSED
 | ||
|             4 => 'REMOVED',  // REMOVED
 | ||
|         ];
 | ||
| 
 | ||
|         // 设置表头
 | ||
|         $sheet->setCellValue('A1', 'Ad ID');
 | ||
|         $sheet->setCellValue('B1', 'Ad Status');
 | ||
|         $sheet->setCellValue('C1', 'Name');
 | ||
|         $sheet->setCellValue('D1', 'Campaign');
 | ||
|         $sheet->setCellValue('E1', 'Ad Set');
 | ||
|         $sheet->setCellValue('F1', 'Delivery');
 | ||
|         $sheet->setCellValue('G1', 'Results');
 | ||
|         $sheet->setCellValue('H1', 'Reach');
 | ||
|         $sheet->setCellValue('I1', 'Revenue');
 | ||
|         $sheet->setCellValue('J1', 'ROAS');
 | ||
|         $sheet->setCellValue('K1', 'beROAS');
 | ||
|         $sheet->setCellValue('L1', 'Profit');
 | ||
|         $sheet->setCellValue('M1', 'Spend');
 | ||
| //        $sheet->setCellValue('N1', 'Customer ID');
 | ||
| //        $sheet->setCellValue('E1', 'Clicks');
 | ||
| //        $sheet->setCellValue('F1', 'Cost Micros');
 | ||
| //        $sheet->setCellValue('G1', 'Conversions');
 | ||
| //        $sheet->setCellValue('H1', 'Conversions Value');
 | ||
| //        $sheet->setCellValue('I1', 'Impressions');
 | ||
| 
 | ||
|         // 填充数据
 | ||
|         $row = 2; // 从第二行开始
 | ||
|         foreach ($ads as $ad) {
 | ||
|             $sheet->setCellValueExplicit('A' . $row, (string)$ad->ad_id, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);  // 设置 ad_id 为文本
 | ||
|             $sheet->setCellValue('B' . $row, $ad_status[$ad->ad_status]);
 | ||
|             $sheet->setCellValue('C' . $row, $ad->ad_name);  // 直接设置 ad_name
 | ||
|             $sheet->setCellValue('D' . $row, $ad->campaign_name);  // 直接设置 ad_name
 | ||
|             $sheet->setCellValue('E' . $row, $ad->ad_group_name);  // 直接设置 ad_name
 | ||
|             $sheet->setCellValue('F' . $row, $ad->delivery);  // 直接设置 ad_name
 | ||
|             $sheet->setCellValue('G' . $row, $ad->results);
 | ||
|             $sheet->setCellValue('H' . $row, $ad->reach);
 | ||
|             $sheet->setCellValue('I' . $row, $ad->revenue);
 | ||
|             $sheet->setCellValue('J' . $row, $ad->roas);
 | ||
|             $sheet->setCellValue('K' . $row, $ad->be_roas);
 | ||
|             $sheet->setCellValue('L' . $row, $ad->profit);
 | ||
|             $sheet->setCellValue('M' . $row, $ad->spend);
 | ||
| //            $sheet->setCellValueExplicit('N' . $row, (string)$ad->customer_id, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);  // 设置 customer_id 为文本
 | ||
| 
 | ||
|             $row++;
 | ||
|         }
 | ||
| 
 | ||
|         // 设置 Excel 文件名
 | ||
|         $fileName = 'Ad_Report_' . $dateRange . '_' . date('Y-m-d_H-i-s') . '.xlsx';
 | ||
| 
 | ||
|         // 创建 Excel 文件并保存
 | ||
|         $writer   = new Xlsx($spreadsheet);
 | ||
|         $filePath = public_path() . '/' . $fileName;
 | ||
| 
 | ||
|         try {
 | ||
|             $writer->save($filePath);
 | ||
|             return response()->download($filePath, $fileName);
 | ||
| //            return ['success' => true, 'file_path' => $filePath];
 | ||
|         } catch (\Exception $e) {
 | ||
|             return ['' => false, 'message' => $e->getMessage()];
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * 获取广告系列列表
 | ||
|      */
 | ||
|     public static function getCampaignList($page, $pageSize, $keyword, $dateRange, $startDate = null, $endDate = null)
 | ||
|     {
 | ||
|         // 基础查询:广告活动和日数据表联接
 | ||
|         $query = Campaign::alias('c')
 | ||
|             ->leftJoin('bps.bps_google_ad_day_data d', 'c.campaign_id = d.campaign_id')
 | ||
|             ->field('c.campaign_id, c.status as campaign_status,c.campaign_name, c.customer_id, 
 | ||
|                      SUM(d.clicks) as clicks, SUM(d.cost_micros) / 1000000 as spend,
 | ||
|                     SUM(d.conversions) as results, SUM(d.conversions_value) as conversions_value, 
 | ||
|                     SUM(d.impressions) 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 . '%');
 | ||
|                 }
 | ||
|             });
 | ||
| 
 | ||
|         // 如果提供了 startDate 和 endDate,则根据范围查询
 | ||
|         if ($startDate && $endDate) {
 | ||
|             $query->whereBetween('d.date', [$startDate, $endDate]);
 | ||
|         } else {
 | ||
|             // 根据日期维度添加聚合条件
 | ||
|             switch ($dateRange) {
 | ||
|                 case 'Today':
 | ||
|                     $query->where('d.date', '=', date('Y-m-d'));
 | ||
|                     break;
 | ||
|                 case 'Yesterday':
 | ||
|                     $query->where('d.date', '=', date('Y-m-d', strtotime('-1 day')));
 | ||
|                     break;
 | ||
|                 case 'Last Week':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 week')));
 | ||
|                     break;
 | ||
|                 case 'Last Month':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 month')));
 | ||
|                     break;
 | ||
|                 case 'Last Year':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 year')));
 | ||
|                     break;
 | ||
|                 default:
 | ||
|                     break;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 获取分页数据
 | ||
|         $campaigns = $query->paginate($pageSize, false, ['page' => $page]);
 | ||
| 
 | ||
|         // 返回分页和总数信息
 | ||
|         return [
 | ||
|             'data' => $campaigns->items(),
 | ||
|             'total' => $campaigns->total(),
 | ||
|             'current_page' => $campaigns->currentPage(),
 | ||
|             'last_page' => $campaigns->lastPage(),
 | ||
|         ];
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * 导出广告系列数据到 Excel
 | ||
|      *
 | ||
|      * @param string $keyword
 | ||
|      * @param string $dateRange
 | ||
|      * @return void
 | ||
|      */
 | ||
|     public static function exportCampaignsToExcel($keyword, $dateRange, $startDate = null, $endDate = null)
 | ||
|     {
 | ||
|         // 获取所有的广告系列数据
 | ||
|         $query = Campaign::alias('c')
 | ||
|             ->leftJoin('bps.bps_google_ad_day_data d', 'c.campaign_id = d.campaign_id')
 | ||
|             ->field('c.campaign_id, c.status as campaign_status,c.campaign_name, c.customer_id, 
 | ||
|                      SUM(d.clicks) as clicks, SUM(d.cost_micros) / 1000000 as spend,
 | ||
|                     SUM(d.conversions) as results, SUM(d.conversions_value) as conversions_value, 
 | ||
|                     SUM(d.impressions) 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 . '%');
 | ||
|                 }
 | ||
|             });
 | ||
| 
 | ||
|         // 如果提供了 startDate 和 endDate,则根据范围查询
 | ||
|         if ($startDate && $endDate) {
 | ||
|             $query->whereBetween('d.date', [$startDate, $endDate]);
 | ||
|             $dateRange = $startDate. 'to'. $endDate;
 | ||
|         } else {
 | ||
|             // 根据日期维度添加聚合条件
 | ||
|             switch ($dateRange) {
 | ||
|                 case 'Today':
 | ||
|                     $query->where('d.date', '=', date('Y-m-d'));
 | ||
|                     break;
 | ||
|                 case 'Yesterday':
 | ||
|                     $query->where('d.date', '=', date('Y-m-d', strtotime('-1 day')));
 | ||
|                     break;
 | ||
|                 case 'Last Week':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 week')));
 | ||
|                     break;
 | ||
|                 case 'Last Month':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 month')));
 | ||
|                     break;
 | ||
|                 case 'Last Year':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 year')));
 | ||
|                     break;
 | ||
|                 default:
 | ||
|                     break;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 获取所有广告系列数据
 | ||
|         $campaigns = $query->select();
 | ||
| 
 | ||
|         // 创建一个新的 Spreadsheet 对象
 | ||
|         $spreadsheet = new Spreadsheet();
 | ||
|         $sheet       = $spreadsheet->getActiveSheet();
 | ||
| 
 | ||
|         $campaignsStatus = [
 | ||
|             0 => 'UNSPECIFIED',  // UNSPECIFIED
 | ||
|             1 => 'UNKNOWN',  // UNKNOWN
 | ||
|             2 => 'ENABLED',  // ENABLED
 | ||
|             3 => 'PAUSED',  // PAUSED
 | ||
|             4 => 'REMOVED',  // REMOVED
 | ||
|         ];
 | ||
| 
 | ||
|         // 设置表头
 | ||
|         $sheet->setCellValue('A1', 'Campaign ID');
 | ||
|         $sheet->setCellValue('B1', 'Status');
 | ||
|         $sheet->setCellValue('C1', 'Name');
 | ||
|         $sheet->setCellValue('D1', 'Delivery');
 | ||
|         $sheet->setCellValue('E1', 'Results');
 | ||
|         $sheet->setCellValue('F1', 'Reach');
 | ||
|         $sheet->setCellValue('G1', 'Revenue');
 | ||
|         $sheet->setCellValue('H1', 'ROAS');
 | ||
|         $sheet->setCellValue('I1', 'beROAS');
 | ||
|         $sheet->setCellValue('J1', 'Profit');
 | ||
|         $sheet->setCellValue('K1', 'Spend');
 | ||
| 
 | ||
|         // 填充数据
 | ||
|         $row = 2; // 从第二行开始
 | ||
|         foreach ($campaigns as $campaign) {
 | ||
| //使用 setCellValueExplicit 显式设置为文本格式
 | ||
|             $sheet->setCellValueExplicit('A' . $row, (string)$campaign->campaign_id, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);  // 设置为文本格式
 | ||
|             $sheet->setCellValue('B' . $row, $campaignsStatus[$campaign->campaign_status]);
 | ||
|             $sheet->setCellValue('C' . $row, $campaign->campaign_name);
 | ||
|             $sheet->setCellValue('D' . $row, $campaign->delivery);  // 直接设置 ad_name
 | ||
|             $sheet->setCellValue('E' . $row, $campaign->results);
 | ||
|             $sheet->setCellValue('F' . $row, $campaign->reach);
 | ||
|             $sheet->setCellValue('G' . $row, $campaign->revenue);
 | ||
|             $sheet->setCellValue('H' . $row, $campaign->roas);
 | ||
|             $sheet->setCellValue('I' . $row, $campaign->be_roas);
 | ||
|             $sheet->setCellValue('J' . $row, $campaign->profit);
 | ||
|             $sheet->setCellValue('K' . $row, $campaign->spend);
 | ||
| //            $sheet->setCellValueExplicit('N' . $row, (string)$campaign->customer_id, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);  // 设置为文本格式
 | ||
|             $row++;
 | ||
|         }
 | ||
| 
 | ||
|         // 设置 Excel 文件名
 | ||
|         $fileName = 'Campaign_Report_' . $dateRange . '_' . date('Y-m-d_H-i-s') . '.xlsx';
 | ||
| 
 | ||
|         // 创建 Excel 文件并保存
 | ||
|         $writer   = new Xlsx($spreadsheet);
 | ||
|         $filePath = public_path() . '/' . $fileName;
 | ||
| 
 | ||
|         try {
 | ||
|             $writer->save($filePath);
 | ||
|             return response()->download($filePath, $fileName);
 | ||
| //            return ['success' => true, 'file_path' => $filePath];
 | ||
|         } catch (\Exception $e) {
 | ||
|             return ['' => false, 'message' => $e->getMessage()];
 | ||
|         }
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * 获取广告系列列表
 | ||
|      */
 | ||
|     public static function getAdGroupList($page, $pageSize, $keyword, $dateRange, $startDate = null, $endDate = null)
 | ||
|     {
 | ||
|         // 初始化查询
 | ||
|         $query = AdGroup::alias('ag')
 | ||
|             ->leftJoin('bps.bps_google_ad_day_data d', 'ag.ad_group_id = d.ad_group_id')
 | ||
|             ->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, 
 | ||
|                       SUM(d.clicks) as clicks, SUM(d.cost_micros) / 1000000 as spend,
 | ||
|                     SUM(d.conversions) as results, SUM(d.conversions_value) as conversions_value, 
 | ||
|                     SUM(d.impressions) 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 . '%');
 | ||
|                 }
 | ||
|             });
 | ||
| 
 | ||
|         // 如果提供了 startDate 和 endDate,则根据范围查询
 | ||
|         if ($startDate && $endDate) {
 | ||
|             $query->whereBetween('d.date', [$startDate, $endDate]);
 | ||
|         } else {
 | ||
|             // 根据日期维度添加聚合条件
 | ||
|             switch ($dateRange) {
 | ||
|                 case 'Today':
 | ||
|                     $query->where('d.date', '=', date('Y-m-d'));
 | ||
|                     break;
 | ||
|                 case 'Yesterday':
 | ||
|                     $query->where('d.date', '=', date('Y-m-d', strtotime('-1 day')));
 | ||
|                     break;
 | ||
|                 case 'Last Week':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 week')));
 | ||
|                     break;
 | ||
|                 case 'Last Month':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 month')));
 | ||
|                     break;
 | ||
|                 case 'Last Year':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 year')));
 | ||
|                     break;
 | ||
|                 default:
 | ||
|                     break;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 分页查询
 | ||
|         try {
 | ||
| 
 | ||
| //            $sql = $query->fetchSql()->select();  // fetchSql() 会返回 SQL 查询语句
 | ||
| //            echo "Executed SQL: " . $sql;  // 输出执行的 SQL
 | ||
| 
 | ||
|             $result = $query->paginate([
 | ||
|                 'list_rows' => $pageSize,  // 每页数量
 | ||
|                 'page' => $page,  // 当前页码
 | ||
|             ]);
 | ||
| 
 | ||
|             // 返回分页数据
 | ||
|             return [
 | ||
|                 'data' => $result->items(),
 | ||
|                 'total' => $result->total(),
 | ||
|                 'current_page' => $result->currentPage(),
 | ||
|                 'last_page' => $result->lastPage(),
 | ||
|             ];
 | ||
|         } catch (DbException $e) {
 | ||
|             // 处理数据库查询错误
 | ||
|             return [
 | ||
|                 'error' => 'Database query failed: ' . $e->getMessage(),
 | ||
|             ];
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * 将广告组数据导出到 Excel 文件
 | ||
|      */
 | ||
|     public static function exportAdGroupsToExcel($keyword = '', $dateRange = 'Today', $startDate = null, $endDate = null)
 | ||
|     {
 | ||
|         // 初始化查询
 | ||
|         $query = AdGroup::alias('ag')
 | ||
|             ->leftJoin('bps.bps_google_ad_day_data d', 'ag.ad_group_id = d.ad_group_id')
 | ||
|             ->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, 
 | ||
|                       SUM(d.clicks) as clicks, SUM(d.cost_micros) / 1000000 as spend,
 | ||
|                     SUM(d.conversions) as results, SUM(d.conversions_value) as conversions_value, 
 | ||
|                     SUM(d.impressions) 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 . '%');
 | ||
|                 }
 | ||
|             });
 | ||
| 
 | ||
| 
 | ||
|         // 如果提供了 startDate 和 endDate,则根据范围查询
 | ||
|         if ($startDate && $endDate) {
 | ||
|             $query->whereBetween('d.date', [$startDate, $endDate]);
 | ||
|             $dateRange = $startDate. 'to'. $endDate;
 | ||
|         } else {
 | ||
|             // 根据日期维度添加聚合条件
 | ||
|             switch ($dateRange) {
 | ||
|                 case 'Today':
 | ||
|                     $query->where('d.date', '=', date('Y-m-d'));
 | ||
|                     break;
 | ||
|                 case 'Yesterday':
 | ||
|                     $query->where('d.date', '=', date('Y-m-d', strtotime('-1 day')));
 | ||
|                     break;
 | ||
|                 case 'Last Week':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 week')));
 | ||
|                     break;
 | ||
|                 case 'Last Month':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 month')));
 | ||
|                     break;
 | ||
|                 case 'Last Year':
 | ||
|                     $query->where('d.date', '>=', date('Y-m-d', strtotime('-1 year')));
 | ||
|                     break;
 | ||
|                 default:
 | ||
|                     break;
 | ||
|             }
 | ||
|         }
 | ||
|         // 获取所有广告组数据
 | ||
|         $ad_groups = $query->select();
 | ||
| 
 | ||
| 
 | ||
|         // 创建一个新的 Spreadsheet 对象
 | ||
|         $spreadsheet = new Spreadsheet();
 | ||
|         $sheet       = $spreadsheet->getActiveSheet();
 | ||
| 
 | ||
|         // 设置表头
 | ||
|         $sheet->setCellValue('A1', 'Ad Group ID');
 | ||
|         $sheet->setCellValue('B1', 'Status');
 | ||
|         $sheet->setCellValue('C1', 'Name');
 | ||
|         $sheet->setCellValue('D1', 'Campaign');
 | ||
|         $sheet->setCellValue('E1', 'Delivery');
 | ||
|         $sheet->setCellValue('F1', 'Results');
 | ||
|         $sheet->setCellValue('G1', 'Reach');
 | ||
|         $sheet->setCellValue('H1', 'Revenue');
 | ||
|         $sheet->setCellValue('I1', 'ROAS');
 | ||
|         $sheet->setCellValue('J1', 'beROAS');
 | ||
|         $sheet->setCellValue('K1', 'Profit');
 | ||
|         $sheet->setCellValue('L1', 'Spend');
 | ||
| 
 | ||
|         $ad_groups_status = [
 | ||
|             0 => 'UNSPECIFIED',  // UNSPECIFIED
 | ||
|             1 => 'UNKNOWN',  // UNKNOWN
 | ||
|             2 => 'ENABLED',  // ENABLED
 | ||
|             3 => 'PAUSED',  // PAUSED
 | ||
|             4 => 'REMOVED',  // REMOVED
 | ||
|         ];
 | ||
| 
 | ||
| 
 | ||
|         // 填充数据
 | ||
|         $row = 2;
 | ||
|         foreach ($ad_groups as $adGroup) {
 | ||
|             // 使用 setCellValueExplicit 显式设置为文本格式
 | ||
|             $sheet->setCellValueExplicit('A' . $row, (string)$adGroup->ad_group_id, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);  // 设置为文本格式
 | ||
| //            $sheet->setCellValueExplicit('B' . $row, (string)$adGroup->campaign_id, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);
 | ||
|             $sheet->setCellValue('B' . $row, $ad_groups_status[$adGroup->ad_group_status]);
 | ||
|             $sheet->setCellValue('C' . $row, $adGroup->ad_group_name);
 | ||
|             $sheet->setCellValue('D' . $row, $adGroup->campaign_name);
 | ||
|             $sheet->setCellValue('E' . $row, $adGroup->delivery);  // 直接设置 ad_name
 | ||
|             $sheet->setCellValue('F' . $row, $adGroup->results);
 | ||
|             $sheet->setCellValue('G' . $row, $adGroup->reach);
 | ||
|             $sheet->setCellValue('H' . $row, $adGroup->revenue);
 | ||
|             $sheet->setCellValue('I' . $row, $adGroup->roas);
 | ||
|             $sheet->setCellValue('J' . $row, $adGroup->be_roas);
 | ||
|             $sheet->setCellValue('K' . $row, $adGroup->profit);
 | ||
|             $sheet->setCellValue('L' . $row, $adGroup->spend);
 | ||
| 
 | ||
| //            $sheet->setCellValueExplicit('M' . $row, (string)$adGroup->customer_id, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);
 | ||
| 
 | ||
|             $row++;
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         // 自动调整所有列宽
 | ||
|         foreach (range('A', 'H') as $column) {
 | ||
|             $spreadsheet->getActiveSheet()->getColumnDimension($column)->setAutoSize(true);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         // 设置 Excel 文件名
 | ||
|         $fileName = 'AdGroup_Report_' . $dateRange . '_' . date('Y-m-d_H-i-s') . '.xlsx';
 | ||
| 
 | ||
|         // 创建 Excel 文件并保存
 | ||
|         $writer   = new Xlsx($spreadsheet);
 | ||
|         $filePath = public_path() . '/' . $fileName;
 | ||
| 
 | ||
|         try {
 | ||
|             $writer->save($filePath);
 | ||
|             return response()->download($filePath, $fileName);
 | ||
| //            return ['success' => true, 'file_path' => $filePath];
 | ||
|         } catch (\Exception $e) {
 | ||
|             return ['' => false, 'message' => $e->getMessage()];
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
| }
 |