标签页角标数字(Accounts、Campaigns、Ad Sets 、Ads、Creatives)
This commit is contained in:
parent
72b5f940c8
commit
da191acf71
@ -97,6 +97,15 @@ 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(
|
||||
$platformType, // 平台类型
|
||||
@ -108,6 +117,8 @@ class BpsAdController
|
||||
$endDate, // 结束日期
|
||||
);
|
||||
|
||||
$result['ad_data_count'] = $ad_data_count;
|
||||
|
||||
// 返回结果
|
||||
return $this->successResponse($result, $request);
|
||||
}
|
||||
@ -382,7 +393,7 @@ class BpsAdController
|
||||
$accountIds = array_unique(array_column($accounts, 'account_id'));
|
||||
// dump($accountIds);
|
||||
// 调用 Service 层查询广告组列表
|
||||
$result = $this->adsInsightService->getCreativeInsightData(
|
||||
$result = $this->adsInsightService::getCreativeInsightData(
|
||||
$platformType,
|
||||
$accountIds, // 客户 ID 数组
|
||||
$page, // 页码
|
||||
|
@ -19,6 +19,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
use think\db\exception\DbException;
|
||||
use think\facade\Db as ThinkDb;
|
||||
use support\Redis;
|
||||
|
||||
class AdsInsightService
|
||||
{
|
||||
@ -29,38 +30,155 @@ class AdsInsightService
|
||||
// 其他状态可以继续添加
|
||||
];
|
||||
|
||||
// Redis 键名前缀
|
||||
const REDIS_KEY_PREFIX = 'ad_data_count:';
|
||||
|
||||
/**
|
||||
* 获取广告数据的各项总数(统一接口)
|
||||
*
|
||||
* @param array $customerIds 客户 ID 数组
|
||||
* @return array 各项 count 统计数据
|
||||
*/
|
||||
public static function getAdCountData($customerIds, $startDate, $endDate)
|
||||
{
|
||||
if (empty($customerIds)) {
|
||||
return [];
|
||||
}
|
||||
// 生成唯一的哈希键
|
||||
$hashKey = self::generateHashKey($customerIds);
|
||||
$redisKey = self::REDIS_KEY_PREFIX . $hashKey;
|
||||
|
||||
// 尝试从 Redis 中获取缓存值
|
||||
$cachedData = Redis::get($redisKey);
|
||||
if (!empty($cachedData)) {
|
||||
return json_decode($cachedData, true);
|
||||
}
|
||||
|
||||
// 没有缓存时重新计算
|
||||
$countData = self::calculateCountData($customerIds, $startDate, $endDate);
|
||||
|
||||
// 缓存到 Redis,有效期 10 分钟
|
||||
Redis::setex($redisKey, 600, json_encode($countData));
|
||||
|
||||
return $countData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 计算广告数据的 count
|
||||
*/
|
||||
protected static function calculateCountData(array $customerIds, $startDate, $endDate)
|
||||
{
|
||||
if (!$startDate || !$endDate) {
|
||||
[$startDate, $endDate] = self::getLastWeekDateRange();
|
||||
}
|
||||
return [
|
||||
'account_list_count' => self::getAccountListCount($customerIds, $startDate, $endDate),
|
||||
'campaign_list_count' => self::getCampaignListCount($customerIds, $startDate, $endDate),
|
||||
'adset_list_count' => self::getAdsetListCount($customerIds, $startDate, $endDate),
|
||||
'ad_list_count' => self::getAdListCount($customerIds, $startDate, $endDate),
|
||||
'creative_list_count' => self::getCreativeListCount($customerIds, $startDate, $endDate),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 Redis 键的唯一哈希值
|
||||
*/
|
||||
protected static function generateHashKey(array $customerIds)
|
||||
{
|
||||
sort($customerIds);
|
||||
return md5(json_encode($customerIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取广告列表的 count
|
||||
*/
|
||||
protected static function getAdListCount(array $customerIds, $startDate, $endDate)
|
||||
{
|
||||
return self::getAdList(0, $customerIds, 1, 1, '', $startDate, $endDate, 0, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取广告系列列表的 count
|
||||
*/
|
||||
protected static function getCampaignListCount(array $customerIds, $startDate, $endDate)
|
||||
{
|
||||
return self::getCampaignList(0, $customerIds, 1, 1, '', $startDate, $endDate, 0, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取广告组列表的 count
|
||||
*/
|
||||
protected static function getAdsetListCount(array $customerIds, $startDate, $endDate)
|
||||
{
|
||||
return self::getAdsetList(0, $customerIds, 1, 1, '', $startDate, $endDate, 0, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取账户列表的 count
|
||||
*/
|
||||
protected static function getAccountListCount(array $customerIds, $startDate, $endDate)
|
||||
{
|
||||
return self::getAccountList(0, $customerIds, 1, 1, '', $startDate, $endDate, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取账户列表的 count
|
||||
*/
|
||||
protected static function getCreativeListCount(array $customerIds, $startDate, $endDate)
|
||||
{
|
||||
return self::getCreativeInsightData(0, $customerIds, 1, 1, '', $startDate, $endDate, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最近 7 天的起始和结束日期
|
||||
*/
|
||||
protected static function getLastWeekDateRange()
|
||||
{
|
||||
$endDate = (int)date('Ymd');
|
||||
$startDate = (int)date('Ymd', strtotime('-6 days'));
|
||||
return [$startDate, $endDate];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取广告系列列表
|
||||
*/
|
||||
public static function getCampaignList($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null, $status = 0)
|
||||
public static function getCampaignList($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null, $status = 0, $countOnly = false)
|
||||
{
|
||||
// 检查 customerIds 是否为空,直接返回空结构
|
||||
if (empty($customerIds)) {
|
||||
return [
|
||||
return $countOnly ? 0 : [
|
||||
'pagination' => [
|
||||
'startIndex' => 0,
|
||||
'maxResults' => $pageSize,
|
||||
'maxResults' => 0,
|
||||
'count' => 0,
|
||||
'pageNo' => $page,
|
||||
'pageSize' => $pageSize,
|
||||
'pages' => 0,
|
||||
],
|
||||
'statistics' => [
|
||||
],
|
||||
'statistics' => [],
|
||||
'data' => [],
|
||||
];
|
||||
}
|
||||
// 动态构建日期条件
|
||||
$dateCondition = '';
|
||||
if ($startDate && $endDate) {
|
||||
$dateCondition = "d.date BETWEEN '{$startDate}' AND '{$endDate}'";
|
||||
} else {
|
||||
}
|
||||
|
||||
// 基础查询:广告活动和日数据表联接
|
||||
$query = BpsAdCampaign::alias('c')
|
||||
->cache(false) // 强制不使用缓存
|
||||
->leftJoin('bps.bps_ads_insights d', "c.campaign_id = d.ad_campaign_id AND c.platform_type = d.platform AND {$dateCondition}")
|
||||
->where('c.account_id', 'in', $customerIds);
|
||||
// 如果只需要记录条数,执行计数查询
|
||||
if ($countOnly) {
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
// 动态构建日期条件
|
||||
$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,
|
||||
COALESCE(SUM(d.assisted_purchases), 0) as assisted_purchases,
|
||||
COALESCE(SUM(d.last_clicked_purchases), 0) as last_clicked_purchases,
|
||||
@ -190,36 +308,44 @@ class AdsInsightService
|
||||
/**
|
||||
* 获取广告组列表
|
||||
*/
|
||||
public static function getAdsetList($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null, $status = 0)
|
||||
public static function getAdsetList($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null, $status = 0, $countOnly = false)
|
||||
{
|
||||
// 检查 customerIds 是否为空,直接返回空结构
|
||||
if (empty($customerIds)) {
|
||||
return [
|
||||
return $countOnly ? 0 : [
|
||||
'pagination' => [
|
||||
'startIndex' => 0,
|
||||
'maxResults' => $pageSize,
|
||||
'maxResults' => 0,
|
||||
'count' => 0,
|
||||
'pageNo' => $page,
|
||||
'pageSize' => $pageSize,
|
||||
'pages' => 0,
|
||||
],
|
||||
'statistics' => [
|
||||
],
|
||||
'statistics' => [],
|
||||
'data' => [],
|
||||
];
|
||||
}
|
||||
|
||||
// 基础查询:广告活动和日数据表联接
|
||||
$query = BpsAdSet::alias('s')
|
||||
->cache(false) // 强制不使用缓存
|
||||
->where('s.account_id', 'in', $customerIds);
|
||||
// 如果只需要记录条数,执行计数查询
|
||||
if ($countOnly) {
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
|
||||
// 动态构建日期条件
|
||||
$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 = BpsAdSet::alias('s')
|
||||
->cache(false) // 强制不使用缓存
|
||||
->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') // 联接广告系列表
|
||||
|
||||
$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,
|
||||
COALESCE(SUM(d.assisted_purchases), 0) as assisted_purchases,
|
||||
COALESCE(SUM(d.last_clicked_purchases), 0) as last_clicked_purchases,
|
||||
@ -348,12 +474,11 @@ class AdsInsightService
|
||||
];
|
||||
}
|
||||
|
||||
public static function getAccountList($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null)
|
||||
public static function getAccountList($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null, $countOnly = false)
|
||||
{
|
||||
|
||||
// 检查 customerIds 是否为空,直接返回空结构
|
||||
// 检查 customerIds 是否为空,直接返回计数为 0
|
||||
if (empty($customerIds)) {
|
||||
return [
|
||||
return $countOnly ? 0 : [
|
||||
'pagination' => [
|
||||
'startIndex' => 0,
|
||||
'maxResults' => $pageSize,
|
||||
@ -366,18 +491,25 @@ class AdsInsightService
|
||||
'data' => [],
|
||||
];
|
||||
}
|
||||
// 构建查询条件
|
||||
$query = ThirdUserAdvertiser::alias('a')
|
||||
->cache(false)
|
||||
->where('a.advertiser_id', 'in', $customerIds);
|
||||
|
||||
// 仅计数时优化查询
|
||||
if ($countOnly) {
|
||||
return $query->count(); // 只查询总记录数
|
||||
}
|
||||
// 动态构建日期条件
|
||||
$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 = 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
|
||||
// 其他联表及字段计算
|
||||
$query->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,
|
||||
@ -463,7 +595,7 @@ class AdsInsightService
|
||||
$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];
|
||||
$platformTypeIds = ['facebook' => 1, 'google' => 2, 'tiktok' => 3];
|
||||
return [
|
||||
'user_id' => $item['advertiser_id'],
|
||||
'platform_type' => $platformTypeIds[$item['third_type']],
|
||||
@ -510,14 +642,14 @@ class AdsInsightService
|
||||
}
|
||||
|
||||
|
||||
public static function getAdList($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null, $status = 0)
|
||||
public static function getAdList($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null, $status = 0, $countOnly = false)
|
||||
{
|
||||
// 检查 customerIds 是否为空,直接返回空结构
|
||||
if (empty($customerIds)) {
|
||||
return [
|
||||
return $countOnly ? 0 : [
|
||||
'pagination' => [
|
||||
'startIndex' => 0,
|
||||
'maxResults' => $pageSize,
|
||||
'maxResults' => 0,
|
||||
'count' => 0,
|
||||
'pageNo' => $page,
|
||||
'pageSize' => $pageSize,
|
||||
@ -528,17 +660,24 @@ class AdsInsightService
|
||||
];
|
||||
}
|
||||
|
||||
// 基础查询:广告活动和日数据表联接
|
||||
$query = BpsAdAd::alias('a')
|
||||
->cache(false) // 强制不使用缓存
|
||||
->where('a.account_id', 'in', $customerIds);
|
||||
// 如果只需要记录条数,执行计数查询
|
||||
if ($countOnly) {
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
// 动态构建日期条件
|
||||
$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 = BpsAdAd::alias('a')
|
||||
->cache(false) // 强制不使用缓存
|
||||
->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
|
||||
$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,
|
||||
COALESCE(SUM(d.assisted_purchases), 0) as assisted_purchases,
|
||||
COALESCE(SUM(d.last_clicked_purchases), 0) as last_clicked_purchases,
|
||||
@ -951,7 +1090,7 @@ class AdsInsightService
|
||||
}
|
||||
|
||||
|
||||
public function getCreativeInsightData($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null)
|
||||
public static function getCreativeInsightData($platformType, $customerIds, $page, $pageSize, $keyword, $startDate = null, $endDate = null, $countOnly = false)
|
||||
{
|
||||
// 1. 创建查询对象,初始化 BpsAdCreativeInsight 查询
|
||||
$creativeDataQuery = BpsAdCreativeInsight::alias('i')
|
||||
@ -969,7 +1108,7 @@ class AdsInsightService
|
||||
if (!empty($customerIds)) {
|
||||
$creativeDataQuery->whereIn('i.account_id', $customerIds);
|
||||
} else {
|
||||
return [
|
||||
return $countOnly ? 0 :[
|
||||
'data' => [],
|
||||
'total' => 0,
|
||||
'statistics' => [],
|
||||
@ -982,6 +1121,10 @@ class AdsInsightService
|
||||
]
|
||||
];
|
||||
}
|
||||
// 仅返回记录数时的逻辑
|
||||
if ($countOnly) {
|
||||
return $creativeDataQuery->count() ?: 0;
|
||||
}
|
||||
|
||||
// 4. 关键词过滤
|
||||
if ($keyword) {
|
||||
|
Loading…
Reference in New Issue
Block a user