Quellcode durchsuchen

头条获取广告数据

PC-202304251453\Administrator vor 5 Monaten
Ursprung
Commit
09d801c1e6

+ 1 - 1
app/command/CostGdt.php

@@ -2,7 +2,7 @@
 
 namespace app\command;
 
-use app\v1\logic\tool\advert\GdtCostHourLogic;
+use app\v1\logic\tool\advertCost\GdtCostHourLogic;
 use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Attribute\AsCommand;
 use Symfony\Component\Console\Input\InputInterface;

+ 63 - 0
app/command/CostTt.php

@@ -0,0 +1,63 @@
+<?php
+
+namespace app\command;
+
+use app\v1\logic\tool\advertCost\TtCostHourLogic;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Output\OutputInterface;
+
+#[AsCommand('cost:tt', 'cost tt')]
+class CostTt extends Command
+{
+    /**
+     * 自定义脚本示例
+     * @return void
+     */
+    protected function configure()
+    {
+        // 用法示例 php webman cost:tt date api_id advertiser_ids
+        // php webman cost:tt 2025-07-30,2025-07-31 0 54970254,60853999
+        $this->addArgument('date', InputArgument::OPTIONAL, '日期范围');
+        $this->addArgument('api_id', InputArgument::OPTIONAL, '需要拉取的API配置ID');
+        $this->addArgument('advertiser_ids', InputArgument::OPTIONAL, '需要拉取的广告账户');
+    }
+
+    /**
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     * @return int
+     */
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $date = $input->getArgument('date');
+        $apiId = (int)$input->getArgument('api_id');
+        $advertiserIds = $input->getArgument('advertiser_ids');
+
+        $params = [];
+
+        if($date){
+            $params['date'] = explode(',', $date);
+        }
+
+        if($apiId){
+            $params['api_id'] = $apiId;
+        }
+
+        if($advertiserIds){
+            $params['advertiser_ids'] = explode(',', $advertiserIds);
+        }
+
+        $output->writeln("\ntt cost sta:" . json_encode($params, JSON_UNESCAPED_UNICODE));
+
+        $res = (new TtCostHourLogic)->run($params);
+
+        $output->writeln("\ntt cost end:" . $res);
+
+        return self::SUCCESS;
+    }
+
+}

+ 1 - 1
app/process/advert/GdtCostHour.php

@@ -2,7 +2,7 @@
 
 namespace app\process\advert;
 use Workerman\Crontab\Crontab;
-use app\v1\logic\tool\advert\GdtCostHourLogic;
+use app\v1\logic\tool\advertCost\GdtCostHourLogic;
 
 class GdtCostHour
 {

+ 74 - 0
app/v1/logic/tool/advertCost/BaseAdvertLogic.php

@@ -0,0 +1,74 @@
+<?php
+
+namespace app\v1\logic\tool\advertCost;
+
+use app\v1\logic\advert\AgentSiteLogic;
+use GuzzleHttp\Client;
+use support\think\Db;
+
+abstract class BaseAdvertLogic
+{
+    protected string $dateTable = "media_cost";
+
+    protected string $hourTable = "media_cost_hour";
+
+    protected string $date;
+
+    protected array $advertiserIds=[];
+
+    protected array $siteMap=[];
+
+    protected int $apiId=0;
+
+    public function run($params=[])
+    {
+        // 重跑用,传数组
+        if(!empty($params['date'])){
+            $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
+            $eDate = !empty($params['date'][1]) ? $params['date'][1] : $params['date'][0];
+            // 检查日期格式是否正确
+            if(!isValidDate($sDate) || !isValidDate($eDate)){
+                return json_encode(["status"=>"error", "msg"=>"日期格式不正确"], 256);
+            }
+        }else{
+            $sDate = date('Y-m-d');
+            $eDate = date('Y-m-d');
+        }
+
+        // 重跑用,传数组
+        if(!empty($params['advertiser_ids'])){
+            $this->advertiserIds = $params['advertiser_ids'];
+        }
+
+        // 重跑用,传int
+        if(!empty($params['api_id'])){
+            $this->apiId = $params['api_id'];
+        }
+
+        $this->siteMap = (new AgentSiteLogic())->getSiteAuth();
+
+        for ($date = $sDate; $date <= $eDate; $date = date('Y-m-d', strtotime($date . '+1 day'))){
+            $this->date = $date;
+            try {
+                $this->initStart();
+            }catch (\Exception $e){
+                return json_encode(["status"=>"error", "msg"=>$e->getMessage()], 256);
+            }
+        }
+
+        $this->reRun();
+
+        return json_encode(["status"=>"success", "msg"=>""], 256);
+    }
+
+    // 重跑
+    protected function reRun(): void
+    {
+        if (date('H') == 8 && date('i') < 20) {
+            $this->date = date('Y-m-d', strtotime("-1 days"));
+            $this->initStart();
+        }
+    }
+
+    abstract protected function initStart();
+}

+ 16 - 76
app/v1/logic/tool/advert/GdtCostHourLogic.php → app/v1/logic/tool/advertCost/GdtCostHourLogic.php

@@ -1,79 +1,19 @@
 <?php
 
-namespace app\v1\logic\tool\advert;
+namespace app\v1\logic\tool\advertCost;
 
-use app\v1\logic\advert\AgentSiteLogic;
 use GuzzleHttp\Client;
 use support\think\Db;
 
-class GdtCostHourLogic
+class GdtCostHourLogic extends BaseAdvertLogic
 {
-    protected string $dateTable = "media_cost";
-
-    protected string $hourTable = "media_cost_hour";
-
-    protected string $date;
-
-    protected array $advertiserIds=[];
-
-    protected array $siteMap=[];
-    private int $apiId=0;
-
-    public function run($params=[])
-    {
-        // 重跑用,传数组
-        if(!empty($params['date'])){
-            $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
-            $eDate = !empty($params['date'][1]) ? $params['date'][1] : $params['date'][0];
-            // 检查日期格式是否正确
-            if(!isValidDate($sDate) || !isValidDate($eDate)){
-                return json_encode(["status"=>"error", "msg"=>"日期格式不正确"], 256);
-            }
-        }else{
-            $sDate = date('Y-m-d');
-            $eDate = date('Y-m-d');
-        }
-
-        // 重跑用,传数组
-        if(!empty($params['advertiser_ids'])){
-            $this->advertiserIds = $params['advertiser_ids'];
-        }
-
-        // 重跑用,传int
-        if(!empty($params['api_id'])){
-            $this->apiId = $params['api_id'];
-        }
-
-        for ($date = $sDate; $date <= $eDate; $date = date('Y-m-d', strtotime($date . '+1 day'))){
-            $this->date = $date;
-            try {
-                $this->initStart();
-            }catch (\Exception $e){
-                return json_encode(["status"=>"error", "msg"=>$e->getMessage()], 256);
-            }
-        }
-
-        $this->reRun();
-
-        return json_encode(["status"=>"success", "msg"=>""], 256);
-    }
-
-    // 重跑
-    protected function reRun(): void
-    {
-        if (date('H') == 8 && date('i') < 20) {
-            $this->date = date('Y-m-d', strtotime("-1 days"));
-            $this->initStart();
-        }
-    }
-
+    // 执行正文
     protected function initStart(): void
     {
-        $tokenMap = $this->getTokenMap();
+        $tokenMap = $this->getGdtTokenMap();
 
-        $accountList = $this->getAccountList();
+        $accountList = $this->getGdtAccountList();
 
-        $this->siteMap = (new AgentSiteLogic())->getSiteAuth();
         // 循环执行
         foreach ($accountList as $account)
         {
@@ -89,13 +29,13 @@ class GdtCostHourLogic
     }
 
     // 获取媒体消耗
-    protected function getGdtCost($advertiser_id, $access_token): array
+    protected function getGdtCost($advertiser_id, $accessToken): array
     {
         $page = 1;
         $data = [];
         do {
             $nonce = md5(time().rand(00000, 99999));
-            $url = 'https://api.e.qq.com/v3.0/hourly_reports/get?access_token='.$access_token.'&timestamp='.time().'&nonce='.$nonce;
+            $url = 'https://api.e.qq.com/v3.0/hourly_reports/get?access_token='.$accessToken.'&timestamp='.time().'&nonce='.$nonce;
             $request_data = [
                 'account_id' => $advertiser_id,
                 'level'      => 'REPORT_LEVEL_ADGROUP',
@@ -154,10 +94,10 @@ class GdtCostHourLogic
                 'agent_id'=> $agent_id,
                 'site_id' => $site_id,
                 'tdate'   => $this->date,
-                'thour'   => $val['hour'],
+                'thour'   => (int)$val['hour'],
             ];
 
-            $data = [
+            $hourData = [
                 'advertiser_id' => $account['advertiser_id'],
                 'ad_show' => $show,
                 'ad_click' => $click,
@@ -170,10 +110,10 @@ class GdtCostHourLogic
 
             $hourId= $db->table($this->hourTable)->where($where)->value("id");
             if($hourId) {
-                $data['id'] = $hourId;
+                $hourData['id'] = $hourId;
             }
             // 保存小时数据
-            $db->table($this->hourTable)->save(array_merge($data, $where));
+            $db->table($this->hourTable)->save(array_merge($hourData, $where));
 
             // 计算天的数据
             $adKey = $game_id . "_" . $site_id . "_" . $ad_id;
@@ -196,7 +136,7 @@ class GdtCostHourLogic
                 'tdate'   => $this->date,
             ];
 
-            $data = [
+            $dateData = [
                 'advertiser_id' => $account['advertiser_id'],
                 'ad_show'   => $value['ad_show'],
                 'ad_click'  => $value['ad_click'],
@@ -209,15 +149,15 @@ class GdtCostHourLogic
 
             $dateId= $db->table($this->dateTable)->where($where)->value("id");
             if($dateId) {
-                $data['id'] = $dateId;
+                $dateData['id'] = $dateId;
             }
             // 保存日数据
-            $db->table($this->dateTable)->save(array_merge($data, $where));
+            $db->table($this->dateTable)->save(array_merge($dateData, $where));
         }
     }
 
     // 获取需要拉取消耗的媒体账户
-    protected function getAccountList(): array
+    protected function getGdtAccountList(): array
     {
         $table = "ad_gdt_account_list";
         $where = [
@@ -234,7 +174,7 @@ class GdtCostHourLogic
             ->column("pmid, advertiser_id, advertiser_name, son_fandian");
     }
 
-    protected function getTokenMap(): array
+    protected function getGdtTokenMap(): array
     {
         $table = "ad_gdt_account";
         $where = [

+ 213 - 0
app/v1/logic/tool/advertCost/TtCostHourLogic.php

@@ -0,0 +1,213 @@
+<?php
+
+namespace app\v1\logic\tool\advertCost;
+
+use GuzzleHttp\Client;
+use support\think\Db;
+
+class TtCostHourLogic extends BaseAdvertLogic
+{
+    // 执行正文
+    protected function initStart(): void
+    {
+        $tokenMap = $this->getTtTokenMap();
+
+        $accountList = $this->getTtAccountList();
+
+        // 循环执行
+        foreach ($accountList as $account)
+        {
+            $accessToken = $tokenMap[$account['pmid']] ?? "";
+            if(!$accessToken) continue;
+
+            // 获取消耗
+            $dataList = $this->getTtCost($account['advertiser_id'], $accessToken);
+
+            // 整理数据入库
+            $this->organizeDataList($account, $dataList);
+        }
+    }
+
+    // 获取媒体消耗
+    protected function getTtCost($advertiser_id, $accessToken): array
+    {
+        $page = 1;
+        $data = [];
+        do {
+            $url = 'https://ad.oceanengine.com/open_api/v3.0/report/custom/get/';
+            $request_data = [
+                'advertiser_id'=>$advertiser_id,
+                'dimensions'=>json_encode(["cdp_project_id","cdp_project_name","ad_platform_cdp_project_action_track_url","ad_platform_cdp_project_download_url","stat_time_hour"]),
+                'metrics'=>json_encode(["stat_cost","show_cnt","click_cnt","convert_cnt"]),
+                'filters'=>'[{"operator":4,"values":["0"],"field":"stat_cost","type":3}]',
+                'start_time'=>$this->date,
+                'end_time'=>$this->date,
+                'order_by'=>json_encode([]),
+                'page'=>$page,
+                'page_size'=>100,
+            ];
+            $options = [
+                "headers" => [
+                    'Access-Token' => $accessToken,
+                    'Content-Type' => 'application/json',
+                ]
+            ];
+            $url = $url."?".http_build_query($request_data);
+
+            $httpClient = new Client(['timeout' => 10]);
+            $res = $httpClient->request('GET', $url, $options);
+            $result = json_decode($res->getBody(), true);
+
+            if (empty($result['data']['rows'])) {
+                break;
+            }
+
+            $data = array_merge($data, $result['data']['rows']);
+            $totalPage = $result['data']['page_info']['total_page'] ?? 1;
+            $page++;
+        } while ($page <= $totalPage);
+
+        return $data;
+    }
+
+    // 整理入库数据列表
+    protected function organizeDataList($account, $dataList): void
+    {
+        if(!$dataList) return;
+
+        $db = Db::connect('db_advert');
+        // 返点率
+        $fandianRate = ($account['son_fandian']>1) ? (1/$account['son_fandian']) : $account['son_fandian'];
+
+        $adData = [];
+        foreach ($dataList as $val) {
+            $cost = $val['metrics']['stat_cost'];
+            if($cost=='0.00') continue;
+
+            $ad_id   = $val['dimensions']['cdp_project_id'];
+            $ad_name = $val['dimensions']['cdp_project_name'];
+            $show    = $val['metrics']['show_cnt'];
+            $click   = $val['metrics']['click_cnt'];
+            $convert = $val['metrics']['convert_cnt'];
+            $hour = (int)explode(' ',$val['dimensions']['stat_time_hour'])[1];
+
+            // Todo 从广告名称中拆分归因数据
+            preg_match("/([\d]*)_([\d]*)_([\d]*)/", $ad_name, $match);
+            $game_id = $match[1] ?? 0;
+            $agent_id = $match[2] ?? 0;
+            $site_id = $match[3] ?? 0;
+
+            // 广告名获取不到则获取监测链接或者下载链接
+            if(!$game_id || empty($this->siteMap[$site_id])){
+                $tjurl = $val['dimensions']['ad_platform_cdp_project_action_track_url'];
+                if(!$tjurl){
+                    $tjurl = $val['dimensions']['ad_platform_cdp_project_download_url'];
+                }
+                preg_match("/([\d]*)_([\d]*)_([\d]*)/", $tjurl, $urlMatch);
+                $game_id = $urlMatch[1] ?? 0;
+                $agent_id = $urlMatch[2] ?? 0;
+                $site_id = $urlMatch[3] ?? 0;
+            }
+
+            if(!$game_id || empty($this->siteMap[$site_id])) continue;
+
+            $where = [
+                'ad_id'   => $ad_id,
+                'game_id' => $game_id,
+                'agent_id'=> $agent_id,
+                'site_id' => $site_id,
+                'tdate'   => $this->date,
+                'thour'   => $hour,
+            ];
+
+            $hourData = [
+                'advertiser_id' => $account['advertiser_id'],
+                'ad_show' => $show,
+                'ad_click' => $click,
+                'ad_convert' => $convert,
+                'ori_money' => $cost,
+                'money' => $cost * $fandianRate,
+                'media_id' => $this->siteMap[$site_id]['media_id'],
+                'auth_id' => $this->siteMap[$site_id]['auth_id'],
+            ];
+
+            $hourId= $db->table($this->hourTable)->where($where)->value("id");
+            if($hourId) {
+                $hourData['id'] = $hourId;
+            }
+            // 保存小时数据
+            $db->table($this->hourTable)->save(array_merge($hourData, $where));
+
+            // 计算天的数据
+            $adKey = $game_id . "_" . $site_id . "_" . $ad_id;
+            $adData[$adKey]['game_id'] = $game_id;
+            $adData[$adKey]['agent_id'] = $agent_id;
+            $adData[$adKey]['site_id'] = $site_id;
+            $adData[$adKey]['ad_id'] = $ad_id;
+            $adData[$adKey]['ad_show'] = !empty($adData[$adKey]['ad_show']) ? $adData[$adKey]['ad_show']+$show : $show;
+            $adData[$adKey]['ad_click'] = !empty($adData[$adKey]['ad_click']) ? $adData[$adKey]['ad_click']+$click : $click;
+            $adData[$adKey]['ad_convert'] = !empty($adData[$adKey]['ad_convert']) ? $adData[$adKey]['ad_convert']+$convert : $convert;
+            $adData[$adKey]['cost'] = !empty($adData[$adKey]['cost']) ? $adData[$adKey]['cost']+$cost : $cost;
+        }
+
+        foreach($adData as $value){
+            $where = [
+                'ad_id'   => $value['ad_id'],
+                'game_id' => $value['game_id'],
+                'agent_id'=> $value['agent_id'],
+                'site_id' => $value['site_id'],
+                'tdate'   => $this->date,
+            ];
+
+            $dateData = [
+                'advertiser_id' => $account['advertiser_id'],
+                'ad_show'   => $value['ad_show'],
+                'ad_click'  => $value['ad_click'],
+                'ad_convert'=> $value['ad_convert'],
+                'ori_money' => $value['cost'],
+                'money'     => $value['cost']*$fandianRate,
+                'media_id' => $this->siteMap[$site_id]['media_id'],
+                'auth_id' => $this->siteMap[$site_id]['auth_id'],
+            ];
+
+            $dateId= $db->table($this->dateTable)->where($where)->value("id");
+            if($dateId) {
+                $dateData['id'] = $dateId;
+            }
+            // 保存日数据
+            $db->table($this->dateTable)->save(array_merge($dateData, $where));
+        }
+    }
+
+    // 获取需要拉取消耗的媒体账户
+    protected function getTtAccountList(): array
+    {
+        $table = "ad_jrtt_account_list";
+        $where = [
+            "status" => 1
+        ];
+
+        if($this->advertiserIds){
+            $where['advertiser_id'] = $this->advertiserIds;
+        }
+
+        return Db::connect('db_advert')
+            ->table($table)
+            ->where($where)
+            ->column("pmid, advertiser_id, advertiser_name, son_fandian");
+    }
+
+    protected function getTtTokenMap(): array
+    {
+        $table = "ad_jrtt_account";
+        $where = [
+            "status" => 1
+        ];
+
+        if($this->apiId){
+            $where['id'] = $this->apiId;
+        }
+
+        return Db::connect('db_advert')->table($table)->where($where)->column("access_token", "id");
+    }
+}