Accounts页面由广告thirdUser改成thirdUserAdvertiser
This commit is contained in:
parent
3d973e378e
commit
3b2d59420b
app
@ -59,6 +59,65 @@ class BpsAdController
|
||||
$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);
|
||||
}
|
||||
// dump($accounts);
|
||||
// 获取客户ID数组
|
||||
$accountIds = array_unique(array_column($accounts, 'account_id'));
|
||||
|
||||
// 调用 Service 层查询广告列表
|
||||
$result = $this->adsInsightService::getAccountList(
|
||||
$platformType, // 平台类型
|
||||
$accountIds, // 客户 ID 数组
|
||||
$page, // 页码
|
||||
$pageSize, // 每页数量
|
||||
$keyword, // 关键字
|
||||
$startDate, // 开始日期
|
||||
$endDate, // 结束日期
|
||||
);
|
||||
|
||||
// 返回结果
|
||||
return $this->successResponse($result, $request);
|
||||
}
|
||||
|
||||
//旧原型方法 作废 2025-1-14
|
||||
public function listThirdUsers2222(Request $request)
|
||||
{
|
||||
$options = $request->all();
|
||||
$options['jwtClaims'] = $request->jwtClaims;
|
||||
|
||||
// 获取请求参数
|
||||
$page = $options['pageNo'] ?? 1; // 页码
|
||||
$pageSize = $options['pageSize'] ?? 1000; // 每页数量
|
||||
@ -83,12 +142,12 @@ class BpsAdController
|
||||
}
|
||||
|
||||
if (empty($users)) {
|
||||
return $this->successResponse(['data'=>[]],$request);
|
||||
return $this->successResponse(['data' => []], $request);
|
||||
}
|
||||
|
||||
// 获取客户 ID 数组,并去重
|
||||
$userIds = array_unique(array_column($users, 'id'));
|
||||
|
||||
// dump($userIds);
|
||||
|
||||
// 调用 Service 层查询第三方用户数据列表
|
||||
$result = $this->adsInsightService::getThirdUserList(
|
||||
@ -124,17 +183,17 @@ class BpsAdController
|
||||
// 根据 platformType 获取广告账户
|
||||
if ($platformType === 1) {
|
||||
if (!$request->refresh_token_facebook) {
|
||||
return $this->successResponse(['data'=>[]],$request);
|
||||
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);
|
||||
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);
|
||||
return $this->successResponse(['data' => []], $request);
|
||||
}
|
||||
$accounts = $this->bpsAdAccountService->getTiktokAdAccounts(['refresh_token' => $request->refresh_token_tiktok]);
|
||||
} else {
|
||||
@ -143,7 +202,7 @@ class BpsAdController
|
||||
}
|
||||
|
||||
if (empty($accounts)) {
|
||||
return $this->successResponse(['data'=>[]],$request);
|
||||
return $this->successResponse(['data' => []], $request);
|
||||
}
|
||||
|
||||
// 获取客户ID数组
|
||||
@ -182,17 +241,17 @@ class BpsAdController
|
||||
// 根据 platformType 获取广告账户
|
||||
if ($platformType === 1) {
|
||||
if (!$request->refresh_token_facebook) {
|
||||
return $this->successResponse(['data'=>[]],$request);
|
||||
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);
|
||||
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);
|
||||
return $this->successResponse(['data' => []], $request);
|
||||
}
|
||||
$accounts = $this->bpsAdAccountService->getTiktokAdAccounts(['refresh_token' => $request->refresh_token_tiktok]);
|
||||
} else {
|
||||
@ -201,7 +260,7 @@ class BpsAdController
|
||||
}
|
||||
|
||||
if (empty($accounts)) {
|
||||
return $this->successResponse(['data'=>[]],$request);
|
||||
return $this->successResponse(['data' => []], $request);
|
||||
}
|
||||
|
||||
// 获取客户ID数组
|
||||
@ -239,17 +298,17 @@ class BpsAdController
|
||||
// 根据 platformType 获取广告账户
|
||||
if ($platformType === 1) {
|
||||
if (!$request->refresh_token_facebook) {
|
||||
return $this->successResponse(['data'=>[]],$request);
|
||||
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);
|
||||
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);
|
||||
return $this->successResponse(['data' => []], $request);
|
||||
}
|
||||
$accounts = $this->bpsAdAccountService->getTiktokAdAccounts(['refresh_token' => $request->refresh_token_tiktok]);
|
||||
} else {
|
||||
@ -258,7 +317,7 @@ class BpsAdController
|
||||
}
|
||||
|
||||
if (empty($accounts)) {
|
||||
return $this->successResponse(['data'=>[]],$request);
|
||||
return $this->successResponse(['data' => []], $request);
|
||||
}
|
||||
|
||||
// 获取客户ID数组
|
||||
@ -297,17 +356,17 @@ class BpsAdController
|
||||
// 根据 platformType 获取广告账户
|
||||
if ($platformType === 1) {
|
||||
if (!$request->refresh_token_facebook) {
|
||||
return $this->successResponse(['data'=>[]],$request);
|
||||
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);
|
||||
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);
|
||||
return $this->successResponse(['data' => []], $request);
|
||||
}
|
||||
$accounts = $this->bpsAdAccountService->getTiktokAdAccounts(['refresh_token' => $request->refresh_token_tiktok]);
|
||||
} else {
|
||||
@ -316,7 +375,7 @@ class BpsAdController
|
||||
}
|
||||
|
||||
if (empty($accounts)) {
|
||||
return $this->successResponse(['data'=>[]],$request);
|
||||
return $this->successResponse(['data' => []], $request);
|
||||
}
|
||||
|
||||
// 获取客户ID数组
|
||||
@ -352,17 +411,17 @@ class BpsAdController
|
||||
// 根据 platformType 获取广告账户
|
||||
if ($platformType === 1) {
|
||||
if (!$request->refresh_token_facebook) {
|
||||
return $this->successResponse(['data'=>[]],$request);
|
||||
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);
|
||||
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);
|
||||
return $this->successResponse(['data' => []], $request);
|
||||
}
|
||||
$accounts = $this->bpsAdAccountService->getTiktokAdAccounts(['refresh_token' => $request->refresh_token_tiktok]);
|
||||
} else {
|
||||
@ -371,7 +430,7 @@ class BpsAdController
|
||||
}
|
||||
|
||||
if (empty($accounts)) {
|
||||
return $this->successResponse(['data'=>[]],$request);
|
||||
return $this->successResponse(['data' => []], $request);
|
||||
}
|
||||
|
||||
// 获取客户ID数组
|
||||
|
@ -13,6 +13,7 @@ use app\model\BpsAdAd;
|
||||
use app\model\ThirdUser;
|
||||
use app\model\Asset;
|
||||
use app\model\AssetRelation;
|
||||
use app\model\ThirdUserAdvertiser;
|
||||
use DateTime;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
@ -81,7 +82,7 @@ class AdsInsightService
|
||||
// 添加关键字过滤条件
|
||||
$query->where(function ($query) use ($keyword, $platformType) {
|
||||
if ($keyword) {
|
||||
$query->where('c.name', 'like', '%' . $keyword . '%');
|
||||
$query->whereRaw('LOWER(c.name) LIKE ?', ['%' . strtolower($keyword) . '%']);
|
||||
}
|
||||
if ($platformType) {
|
||||
$platformType = (int)$platformType;
|
||||
@ -125,8 +126,8 @@ class AdsInsightService
|
||||
|
||||
// 获取分页数据
|
||||
// $campaigns = $query->paginate($pageSize, false, ['page' => $page]);
|
||||
// 获取分页数据
|
||||
$page = max(1, (int)$page); // 确保页码不小于 1
|
||||
// 获取分页数据
|
||||
$page = max(1, (int)$page); // 确保页码不小于 1
|
||||
// $ads = $query->page($page, $pageSize)->select();
|
||||
$campaigns = $query->limit(($page - 1) * $pageSize, $pageSize)->select();
|
||||
|
||||
@ -241,7 +242,8 @@ class AdsInsightService
|
||||
// 添加关键字过滤条件
|
||||
$query->where(function ($query) use ($keyword, $platformType) {
|
||||
if ($keyword) {
|
||||
$query->where('s.name', 'like', '%' . $keyword . '%');
|
||||
// $query->where('s.name', 'like', '%' . $keyword . '%');
|
||||
$query->whereRaw('LOWER(s.name) LIKE ?', ['%' . strtolower($keyword) . '%']);
|
||||
}
|
||||
if ($platformType) {
|
||||
$platformType = (int)$platformType;
|
||||
@ -286,7 +288,7 @@ class AdsInsightService
|
||||
|
||||
// 获取分页数据
|
||||
// $adsets = $query->paginate($pageSize, false, ['page' => $page]);
|
||||
$page = max(1, (int)$page); // 确保页码不小于 1
|
||||
$page = max(1, (int)$page); // 确保页码不小于 1
|
||||
$adsets = $query->limit(($page - 1) * $pageSize, $pageSize)->select();
|
||||
|
||||
// 确保数据格式统一
|
||||
@ -346,6 +348,168 @@ class AdsInsightService
|
||||
];
|
||||
}
|
||||
|
||||
public static function getAccountList($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null)
|
||||
{
|
||||
|
||||
// 检查 customerIds 是否为空,直接返回空结构
|
||||
if (empty($customerIds)) {
|
||||
return [
|
||||
'pagination' => [
|
||||
'startIndex' => 0,
|
||||
'maxResults' => $pageSize,
|
||||
'count' => 0,
|
||||
'pageNo' => $page,
|
||||
'pageSize' => $pageSize,
|
||||
'pages' => 0,
|
||||
],
|
||||
'statistics' => [],
|
||||
'data' => [],
|
||||
];
|
||||
}
|
||||
|
||||
// 动态构建日期条件
|
||||
$dateCondition = '';
|
||||
if ($startDate && $endDate) {
|
||||
$dateCondition = "d.date BETWEEN '{$startDate}' AND '{$endDate}'";
|
||||
}
|
||||
|
||||
// 基础查询:广告和日数据表联接
|
||||
$query = ThirdUserAdvertiser::alias('a')
|
||||
->cache(false) // 强制不使用缓存
|
||||
->leftJoin('bps.bps_ads_insights d', "a.advertiser_id = d.account_id AND {$dateCondition}")
|
||||
->leftJoin('bps.bps_third_user u', 'a.doc_ = u.id') // 联接广告组表,获取 ad_set_name
|
||||
->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,
|
||||
COALESCE(SUM(d.clicks), 0) as clicks,
|
||||
COALESCE(SUM(d.spend) / 1000000, 0) as spend,
|
||||
COALESCE(SUM(d.impressions), 0) as impressions,
|
||||
COALESCE(SUM(d.adds_to_cart), 0) as adds_to_cart,
|
||||
COALESCE(SUM(d.cost_per_atc), 0) as cost_per_atc,
|
||||
COALESCE(SUM(d.purchases), 0) as purchases,
|
||||
COALESCE(SUM(d.purchases_value) / 1000000, 0) as purchases_value,
|
||||
COALESCE(SUM(d.revenue) / 1000000, 0) as revenue,
|
||||
COALESCE(SUM(d.total_cost) / 1000000, 0) as total_cost,
|
||||
-1 as conversion_rate, -1 as roas, -1 as ctr, -1 as net_profit, -1 as net_profit_margin, -1 as net_profit_on_ad_spend')
|
||||
->group('a.advertiser_id, a.advertiser_name,u.third_type')
|
||||
->where('a.advertiser_id', 'in', $customerIds); // 添加 customerIds 条件
|
||||
// 如果传入了 status 参数,按状态筛选
|
||||
// if ($status !== 0) {
|
||||
// $query->where('a.status', '=', $status);
|
||||
// }
|
||||
// 添加关键字过滤条件
|
||||
$query->where(function ($query) use ($keyword, $platformType) {
|
||||
if ($keyword) {
|
||||
$query->whereRaw('LOWER(a.advertiser_name) LIKE ?', ['%' . strtolower($keyword) . '%']);
|
||||
}
|
||||
if ($platformType) {
|
||||
$a = (int)$platformType;
|
||||
$platformTypeNames = [1 => 'facebook', 2 => 'google', 3 => 'tiktok'];
|
||||
$query->where('u.third_type', '=', $platformTypeNames[$a]);
|
||||
}
|
||||
});
|
||||
$query->order('u.third_type', 'asc');
|
||||
|
||||
// 获取所有符合条件的数据(不分页)
|
||||
$allAccounts = $query->select()->toArray();
|
||||
|
||||
// 汇总统计数据
|
||||
$total_spend = array_sum(array_column($allAccounts, 'spend'));
|
||||
$total_cost = array_sum(array_column($allAccounts, 'total_cost'));
|
||||
$total_impressions = array_sum(array_column($allAccounts, 'impressions'));
|
||||
$total_clicks = array_sum(array_column($allAccounts, 'clicks'));
|
||||
$total_purchases_value = array_sum(array_column($allAccounts, 'purchases_value'));
|
||||
$total_revenue = array_sum(array_column($allAccounts, 'revenue'));
|
||||
$total_purchases = array_sum(array_column($allAccounts, 'purchases'));
|
||||
$cost_per_purchase = $total_purchases == 0 ? 0 : round($total_spend / $total_purchases, 2);
|
||||
|
||||
$statistics = [
|
||||
'assisted_purchases' => array_sum(array_column($allAccounts, 'assisted_purchases')),
|
||||
'last_clicked_purchases' => array_sum(array_column($allAccounts, 'last_clicked_purchases')),
|
||||
'roas' => $total_spend == 0 ? '-' : round($total_purchases_value / $total_spend, 2),
|
||||
'amount_spend' => '$' . number_format($total_spend, 2) ?: '$0.00', // 格式化支出
|
||||
'clicks' => $total_clicks,
|
||||
'impressions' => array_sum(array_column($allAccounts, 'impressions')),
|
||||
'adds_to_cart' => array_sum(array_column($allAccounts, 'adds_to_cart')),
|
||||
'cost_per_atc' => array_sum(array_column($allAccounts, 'cost_per_atc')),
|
||||
'purchases' => array_sum(array_column($allAccounts, 'purchases')),
|
||||
'purchases_value' => array_sum(array_column($allAccounts, 'purchases_value')),
|
||||
'cost_per_purchase' => '$' . number_format($cost_per_purchase, 2) ?: '$0.00',
|
||||
'revenue' => '$' . number_format(array_sum(array_column($allAccounts, 'revenue')), 2) ?: '$0.00', // 格式化收入
|
||||
'total_cost' => '$' . number_format($total_cost, 2) ?: '$0.00', // 格式化总成本
|
||||
'conversion_rate' => $total_clicks == 0 ? '-' : round(($total_purchases / $total_clicks) * 100, 2) . '%', // 转换率
|
||||
'net_profit' => ($total_revenue - $total_cost) >= 0 ? '+$' . number_format($total_revenue - $total_cost, 2) : '-$' . number_format(abs($total_revenue - $total_cost), 2), // 净利润
|
||||
'net_profit_margin' => $total_revenue == 0 ? '-' : round(($total_revenue - $total_cost) / $total_revenue, 2) * 100 . '%', // 净利润率
|
||||
'net_profit_on_ad_spend' => $total_spend == 0 ? '-' : round(($total_revenue - $total_cost) / $total_spend, 2) * 100 . '%', // 平均广告花费的净利润
|
||||
'ctr' => ($total_impressions > 0) ? number_format(($total_clicks / $total_impressions) * 100, 2) . '%' : '-', // 格式化为百分比
|
||||
];
|
||||
|
||||
|
||||
// 获取分页数据
|
||||
$page = max(1, (int)$page); // 确保页码不小于 1
|
||||
// $ads = $query->page($page, $pageSize)->select();
|
||||
$accounts = $query->limit(($page - 1) * $pageSize, $pageSize)->select();
|
||||
// dump($ads);
|
||||
|
||||
// 确保数据格式统一
|
||||
$result = array_map(function ($item) {
|
||||
// CTR 的计算:点击率 = 点击数 / 展示数
|
||||
$ctr = $item['impressions'] > 0 ? number_format(($item['clicks'] / $item['impressions']) * 100, 2) . '%' : '-';
|
||||
// Conversion Rate 的计算:转换率 = 购买数 / 点击数
|
||||
$conversion_rate = $item['clicks'] > 0 ? round(($item['purchases'] / $item['clicks']) * 100, 2) . '%' : '-';
|
||||
// Net Profit 的计算:净利润 = 收入 - 总成本
|
||||
$net_profit = ($item['revenue'] - $item['total_cost']) >= 0 ? '+$' . number_format($item['revenue'] - $item['total_cost'], 2) : '-$' . number_format(abs($item['revenue'] - $item['total_cost']), 2);
|
||||
// Net Profit Margin 的计算:净利润率 = 净利润 / 收入
|
||||
$net_profit_margin = $item['revenue'] > 0 ? round(($item['revenue'] - $item['total_cost']) / $item['revenue'], 2) * 100 . '%' : '-';
|
||||
// Net Profit on Ad Spend 的计算:广告支出净利润 = (收入 - 总成本) / 广告支出
|
||||
$net_profit_on_ad_spend = $item['spend'] > 0 ? round(($item['revenue'] - $item['total_cost']) / $item['spend'], 2) * 100 . '%' : '-';
|
||||
$platformTypeIds = [ 'facebook' => 1, 'google' => 2, 'tiktok' => 3];
|
||||
return [
|
||||
'user_id' => $item['advertiser_id'],
|
||||
'platform_type' => $platformTypeIds[$item['third_type']],
|
||||
'advertiser_name' => $item['advertiser_name'] ?: '-', // 若 name 为空则显示 '-'
|
||||
// 'ad_set_name' => $item['ad_set_name'] ?: '-', // 若 name 为空则显示 '-'
|
||||
// 'status' => $item['status'],
|
||||
'assisted_purchases' => $item['assisted_purchases'],
|
||||
'last_clicked_purchases' => $item['last_clicked_purchases'],
|
||||
'roas' => $item['spend'] == 0 ? '-' : round($item['purchases_value'] / $item['spend'], 2),
|
||||
'spend' => '$' . number_format($item['spend'], 2), // 格式化支出
|
||||
'amount_spend' => '$' . number_format($item['spend'], 2), // 格式化支出
|
||||
'impressions' => $item['impressions'],
|
||||
'clicks' => $item['clicks'],
|
||||
'ctr' => $ctr, // CTR 字段
|
||||
'adds_to_cart' => $item['adds_to_cart'],
|
||||
'cost_per_atc' => $item['cost_per_atc'],
|
||||
'purchases' => $item['purchases'],
|
||||
'purchases_value' => '$' . number_format($item['purchases_value'], 2), // 格式化购买金额
|
||||
'cost_per_purchase' => $item['purchases'] > 0 ? '$' . number_format(($item['spend'] / $item['purchases']), 2) : '$0.00',
|
||||
'revenue' => '$' . number_format($item['revenue'], 2), // 格式化收入
|
||||
'total_cost' => '$' . number_format($item['total_cost'], 2), // 格式化总成本
|
||||
'conversion_rate' => $conversion_rate,
|
||||
'net_profit' => $net_profit,
|
||||
'net_profit_margin' => $net_profit_margin,
|
||||
'net_profit_on_ad_spend' => $net_profit_on_ad_spend,
|
||||
];
|
||||
}, $accounts->toArray());
|
||||
|
||||
// Pagination 数据
|
||||
$pagination = [
|
||||
'startIndex' => ($page - 1) * $pageSize + 1, // 确保索引从 1 开始
|
||||
'maxResults' => count($accounts), // 当前页实际返回数据数量
|
||||
'count' => count($allAccounts), // 符合条件的总记录数
|
||||
'pageNo' => $page, // 当前页码
|
||||
'pageSize' => $pageSize, // 每页条数
|
||||
'pages' => (int)ceil(count($allAccounts) / $pageSize), // 总页数
|
||||
];
|
||||
|
||||
return [
|
||||
'pagination' => $pagination,
|
||||
'statistics' => $statistics,
|
||||
'data' => $result,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public static function getAdList($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null, $status = 0)
|
||||
{
|
||||
// 检查 customerIds 是否为空,直接返回空结构
|
||||
@ -397,7 +561,8 @@ class AdsInsightService
|
||||
// 添加关键字过滤条件
|
||||
$query->where(function ($query) use ($keyword, $platformType) {
|
||||
if ($keyword) {
|
||||
$query->where('a.name', 'like', '%' . $keyword . '%');
|
||||
// $query->where('a.name', 'like', '%' . $keyword . '%');
|
||||
$query->whereRaw('LOWER(a.name) LIKE ?', ['%' . strtolower($keyword) . '%']);
|
||||
}
|
||||
if ($platformType) {
|
||||
$platformType = (int)$platformType;
|
||||
@ -440,9 +605,8 @@ class AdsInsightService
|
||||
];
|
||||
|
||||
|
||||
|
||||
// 获取分页数据
|
||||
$page = max(1, (int)$page); // 确保页码不小于 1
|
||||
$page = max(1, (int)$page); // 确保页码不小于 1
|
||||
// $ads = $query->page($page, $pageSize)->select();
|
||||
$ads = $query->limit(($page - 1) * $pageSize, $pageSize)->select();
|
||||
// dump($ads);
|
||||
@ -697,14 +861,14 @@ class AdsInsightService
|
||||
$aggregatedUsers[$userId]['net_profit_on_ad_spend'] = $net_profit_on_ad_spend;
|
||||
}
|
||||
// 如果 aggregatedUsers 为空,返回默认的数据结构
|
||||
if (empty($aggregatedUsers)) {
|
||||
if (empty($aggregatedUsers) && !$keyword) {
|
||||
$emptyUser = [];
|
||||
$query = ThirdUser::alias('u')
|
||||
->cache(false) // 强制不使用缓存
|
||||
->leftJoin('bps.bps_third_user_advertiser a', "u.id = a.doc_")
|
||||
->field('u.id as user_id,u.third_type,a.advertiser_name');
|
||||
// 添加关键字过滤条件
|
||||
$query->where(function ($query) use ($keyword, $platformType) {
|
||||
$query->where(function ($query) use ($platformType) {
|
||||
// if ($keyword) {
|
||||
// $query->where('a.advertiser_name', 'like', '%' . $keyword . '%');
|
||||
// }
|
||||
@ -773,10 +937,10 @@ class AdsInsightService
|
||||
|
||||
'startIndex' => ($page - 1) * $pageSize + 1, // 确保索引从 1 开始
|
||||
'maxResults' => count($dataWithoutKeys), // 当前页实际返回数据数量
|
||||
'count' => count($allUsers), // 符合条件的总记录数
|
||||
'count' => count($dataWithoutKeys), // 符合条件的总记录数
|
||||
'pageNo' => $page, // 当前页码
|
||||
'pageSize' => $pageSize, // 每页条数
|
||||
'pages' => (int)ceil(count($allUsers) / $pageSize), // 总页数
|
||||
'pages' => (int)ceil(count($dataWithoutKeys) / $pageSize), // 总页数
|
||||
];
|
||||
|
||||
return [
|
||||
@ -821,7 +985,8 @@ class AdsInsightService
|
||||
|
||||
// 4. 关键词过滤
|
||||
if ($keyword) {
|
||||
$creativeDataQuery->where('c.name', 'like', '%' . $keyword . '%'); // 在 bps_ads_creative 表中查找关键词
|
||||
// $creativeDataQuery->where('c.name', 'like', '%' . $keyword . '%'); // 在 bps_ads_creative 表中查找关键词
|
||||
$creativeDataQuery->whereRaw('LOWER(c.name) LIKE ?', ['%' . strtolower($keyword) . '%']); // 在 bps_ads_creative 表中查找关键词
|
||||
}
|
||||
|
||||
// 5. 数据聚合(按 creative_id 和其他字段)
|
||||
@ -920,7 +1085,7 @@ class AdsInsightService
|
||||
$creativeSummaryData[$creativeId]['video_plays_75_rate'] += $creativeData['video_plays_75_rate'];
|
||||
$creativeSummaryData[$creativeId]['video_plays_100_rate'] += $creativeData['video_plays_100_rate'];
|
||||
// 计算 ROAS
|
||||
$roas = $creativeSummaryData[$creativeId]['spend'] > 0
|
||||
$roas = $creativeSummaryData[$creativeId]['spend'] > 0
|
||||
? $creativeSummaryData[$creativeId]['revenue'] / $creativeSummaryData[$creativeId]['spend']
|
||||
: 0;
|
||||
$creativeSummaryData[$creativeId]['roas'] = $roas > 0 ? number_format($roas, 2) . 'X' : '-';
|
||||
@ -1037,7 +1202,7 @@ class AdsInsightService
|
||||
];
|
||||
}, $creativeSummaryData);
|
||||
// $formattedData = array_values($creativeSummaryData); // 未分页处理
|
||||
$pagedData = array_slice($creativeSummaryData, $startIndex, $pageSize); // 分页处理
|
||||
$pagedData = array_slice(array_values($formattedData), $startIndex, $pageSize); // 分页处理
|
||||
// 9. 返回分页数据
|
||||
return [
|
||||
'data' => $pagedData,
|
||||
|
@ -145,6 +145,7 @@ class BpsAdAccountService
|
||||
->where('tu.user_id', $options['uid']) // 筛选 third_type 为 google 的记录
|
||||
->where('tu.access_token', '<>', '') // 筛选 access_token 不为空的记录
|
||||
->field('tua.advertiser_id as account_id, tu.access_token as refresh_token') // 获取 advertiser_id 字段
|
||||
->order('tu.third_type', 'asc') // 获取 advertiser_id 字段
|
||||
->select(); // 执行查询
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user