607 lines
26 KiB
PHP
607 lines
26 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')
|
|
->cache(false) // 强制不使用缓存
|
|
->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'); // 关联广告系列表
|
|
// 动态拼接 LEFT JOIN 的 ON 条件
|
|
$onCondition = 'a.ad_id = d.ad_id';
|
|
if ($startDate && $endDate) {
|
|
$onCondition .= " AND d.date BETWEEN '{$startDate}' AND '{$endDate}'";
|
|
} else {
|
|
switch ($dateRange) {
|
|
case 'Today':
|
|
$onCondition .= " AND d.date = '" . date('Y-m-d') . "'";
|
|
break;
|
|
case 'Yesterday':
|
|
$onCondition .= " AND d.date = '" . date('Y-m-d', strtotime('-1 day')) . "'";
|
|
break;
|
|
case 'Last Week':
|
|
$onCondition .= " AND d.date >= '" . date('Y-m-d', strtotime('-1 week')) . "'";
|
|
break;
|
|
case 'Last Month':
|
|
$onCondition .= " AND d.date >= '" . date('Y-m-d', strtotime('-1 month')) . "'";
|
|
break;
|
|
case 'Last Year':
|
|
$onCondition .= " AND d.date >= '" . date('Y-m-d', strtotime('-1 year')) . "'";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 添加 LEFT JOIN 日数据表
|
|
$query->leftJoin('bps.bps_google_ad_day_data d', $onCondition);
|
|
// 添加字段、分组和查询条件
|
|
$query->field('a.ad_id, -1 as ad_name, a.status as ad_status, a.customer_id, a.ad_group_id, g.ad_group_name as ad_group_name, a.campaign_id, c.campaign_name as campaign_name,
|
|
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('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')
|
|
->where(function ($query) use ($keyword) {
|
|
if ($keyword) {
|
|
$query->where('a.ad_name', 'like', '%' . $keyword . '%');
|
|
}
|
|
});
|
|
|
|
// 获取查询结果
|
|
$ads = $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;
|
|
}, $ads->items());
|
|
|
|
// dump($query->getLastSql());
|
|
|
|
// 返回分页和总数信息
|
|
return [
|
|
'data' => $result,
|
|
'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')
|
|
->cache(false) // 强制不使用缓存
|
|
->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'); // 关联广告系列表
|
|
// 动态拼接 LEFT JOIN 的 ON 条件
|
|
$onCondition = 'a.ad_id = d.ad_id';
|
|
if ($startDate && $endDate) {
|
|
$onCondition .= " AND d.date BETWEEN '{$startDate}' AND '{$endDate}'";
|
|
} else {
|
|
switch ($dateRange) {
|
|
case 'Today':
|
|
$onCondition .= " AND d.date = '" . date('Y-m-d') . "'";
|
|
break;
|
|
case 'Yesterday':
|
|
$onCondition .= " AND d.date = '" . date('Y-m-d', strtotime('-1 day')) . "'";
|
|
break;
|
|
case 'Last Week':
|
|
$onCondition .= " AND d.date >= '" . date('Y-m-d', strtotime('-1 week')) . "'";
|
|
break;
|
|
case 'Last Month':
|
|
$onCondition .= " AND d.date >= '" . date('Y-m-d', strtotime('-1 month')) . "'";
|
|
break;
|
|
case 'Last Year':
|
|
$onCondition .= " AND d.date >= '" . date('Y-m-d', strtotime('-1 year')) . "'";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 添加 LEFT JOIN 日数据表
|
|
$query->leftJoin('bps.bps_google_ad_day_data d', $onCondition);
|
|
// 添加字段、分组和查询条件
|
|
$query->field('a.ad_id, -1 as ad_name, a.status as ad_status, a.customer_id, a.ad_group_id, g.ad_group_name as ad_group_name, a.campaign_id, c.campaign_name as campaign_name,
|
|
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('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')
|
|
->where(function ($query) use ($keyword) {
|
|
if ($keyword) {
|
|
$query->where('a.ad_name', 'like', '%' . $keyword . '%');
|
|
}
|
|
});
|
|
|
|
|
|
// 获取所有广告数据
|
|
$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)
|
|
{
|
|
// 动态构建日期条件
|
|
$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
|
|
*
|
|
* @param string $keyword
|
|
* @param string $dateRange
|
|
* @return void
|
|
*/
|
|
public static function exportCampaignsToExcel($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->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)
|
|
{
|
|
// 动态构建日期条件
|
|
$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 static function exportAdGroupsToExcel($keyword = '', $dateRange = 'Today', $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 . '%');
|
|
}
|
|
});
|
|
// 获取所有广告组数据
|
|
$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()];
|
|
}
|
|
}
|
|
|
|
}
|