PC-202304251453\Administrator 5 месяцев назад
Родитель
Сommit
3170e9dfe9

+ 50 - 0
app/command/CostGdt.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace app\command;
+
+use app\v1\logic\tool\advert\GdtCostHourLogic;
+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:gdt', 'cost gdt')]
+class CostGdt extends Command
+{
+
+    /**
+     * 自定义脚本示例
+     * @return void
+     * 用法 php webman cost:gdt 2025-07-30,2025-07-31 54970254,60853999
+     */
+    protected function configure()
+    {
+        $this->addArgument('date', InputArgument::OPTIONAL, 'date');
+        $this->addArgument('advertiser_ids', InputArgument::OPTIONAL, 'advertiser_ids');
+    }
+
+    /**
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     * @return int
+     */
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $date = $input->getArgument('date');
+        $advertiser_ids = $input->getArgument('advertiser_ids');
+
+        $params = [
+            'date' => explode(',', $date),
+            'advertiser_ids' => explode(',', $advertiser_ids),
+        ];
+
+        $res = (new GdtCostHourLogic)->run($params);
+
+        $output->writeln('gdt cost:' . $res);
+
+        return self::SUCCESS;
+    }
+
+}

+ 5 - 0
app/functions.php

@@ -2,3 +2,8 @@
 /**
 /**
  * Here is your custom functions.
  * Here is your custom functions.
  */
  */
+function isValidDate($date, $format = 'Y-m-d'): bool
+{
+    $d = DateTime::createFromFormat($format, $date);
+    return $d && $d->format($format) === $date;
+}

+ 16 - 0
app/process/advert/GdtCostHour.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace app\process\advert;
+use Workerman\Crontab\Crontab;
+use app\v1\logic\tool\advert\GdtCostHourLogic;
+
+class GdtCostHour
+{
+    public function onWorkerStart(): void
+    {
+        // 每 10分钟执行一次
+        new Crontab('0 */10 * * * *', function() {
+            (new GdtCostHourLogic())->run();
+        });
+    }
+}

+ 6 - 6
app/process/dataReport/BaseTotal.php

@@ -1,8 +1,8 @@
 <?php
 <?php
 
 
 namespace app\process\dataReport;
 namespace app\process\dataReport;
-use app\v1\logic\tool\BaseTotalDayLogic;
-use app\v1\logic\tool\BaseTotalHourLogic;
+use app\v1\logic\tool\dataReport\BaseTotalDayDataReportLogic;
+use app\v1\logic\tool\dataReport\BaseTotalHourDataReportLogic;
 use Workerman\Crontab\Crontab;
 use Workerman\Crontab\Crontab;
 
 
 /**
 /**
@@ -14,12 +14,12 @@ class BaseTotal
     {
     {
         // 每5分钟执行一次
         // 每5分钟执行一次
         new Crontab('0 */5 * * * *', function() {
         new Crontab('0 */5 * * * *', function() {
-            (new BaseTotalDayLogic())->run();
+            (new BaseTotalDayDataReportLogic())->run();
         });
         });
 
 
         // 每5分钟执行一次
         // 每5分钟执行一次
         new Crontab('0 */5 * * * *', function() {
         new Crontab('0 */5 * * * *', function() {
-            (new BaseTotalHourLogic())->run();
+            (new BaseTotalHourDataReportLogic())->run();
         });
         });
     }
     }
 
 
@@ -29,11 +29,11 @@ class BaseTotal
         $params = $args ? json_decode($args, true) : [];
         $params = $args ? json_decode($args, true) : [];
 
 
         if(!empty($params["type"]) && $params["type"] == "day"){
         if(!empty($params["type"]) && $params["type"] == "day"){
-            return (new BaseTotalDayLogic())->run($params);
+            return (new BaseTotalDayDataReportLogic())->run($params);
         }
         }
 
 
         if(!empty($params["type"]) && $params["type"] == "hour"){
         if(!empty($params["type"]) && $params["type"] == "hour"){
-            return (new BaseTotalHourLogic())->run($params);
+            return (new BaseTotalHourDataReportLogic())->run($params);
         }
         }
 
 
         return "无执行内容";
         return "无执行内容";

+ 3 - 3
app/process/dataReport/BasicActiveDay.php

@@ -1,7 +1,7 @@
 <?php
 <?php
 
 
 namespace app\process\dataReport;
 namespace app\process\dataReport;
-use app\v1\logic\tool\BasicActiveDayLogic;
+use app\v1\logic\tool\dataReport\BasicActiveDayDataReportLogic;
 use Workerman\Crontab\Crontab;
 use Workerman\Crontab\Crontab;
 
 
 /**
 /**
@@ -13,7 +13,7 @@ class BasicActiveDay
     {
     {
         // 每1小时执行一次
         // 每1小时执行一次
         new Crontab('10 */1 * * *', function() {
         new Crontab('10 */1 * * *', function() {
-            (new BasicActiveDayLogic())->run();
+            (new BasicActiveDayDataReportLogic())->run();
         });
         });
     }
     }
 
 
@@ -22,6 +22,6 @@ class BasicActiveDay
     {
     {
         $params = $args ? json_decode($args, true) : [];
         $params = $args ? json_decode($args, true) : [];
 
 
-        return (new BasicActiveDayLogic())->run($params);
+        return (new BasicActiveDayDataReportLogic())->run($params);
     }
     }
 }
 }

+ 6 - 6
app/process/dataReport/GameRegPay.php

@@ -1,8 +1,8 @@
 <?php
 <?php
 
 
 namespace app\process\dataReport;
 namespace app\process\dataReport;
-use app\v1\logic\tool\GameRegPayDayLogic;
-use app\v1\logic\tool\GameRegPayMonthLogic;
+use app\v1\logic\tool\dataReport\GameRegPayDayDataReportLogic;
+use app\v1\logic\tool\dataReport\GameRegPayMonthDataReportLogic;
 use Workerman\Crontab\Crontab;
 use Workerman\Crontab\Crontab;
 
 
 /**
 /**
@@ -14,12 +14,12 @@ class GameRegPay
     {
     {
         // 每2小时执行一次
         // 每2小时执行一次
         new Crontab('0 */2 * * *', function() {
         new Crontab('0 */2 * * *', function() {
-            (new GameRegPayMonthLogic())->run();
+            (new GameRegPayMonthDataReportLogic())->run();
         });
         });
 
 
         // 每5分钟执行一次
         // 每5分钟执行一次
         new Crontab('0 */5 * * * *', function() {
         new Crontab('0 */5 * * * *', function() {
-            (new GameRegPayDayLogic())->run();
+            (new GameRegPayDayDataReportLogic())->run();
         });
         });
     }
     }
 
 
@@ -29,11 +29,11 @@ class GameRegPay
         $params = $args ? json_decode($args, true) : [];
         $params = $args ? json_decode($args, true) : [];
 
 
         if(!empty($params["type"]) && $params["type"] == "month"){
         if(!empty($params["type"]) && $params["type"] == "month"){
-            return (new GameRegPayMonthLogic())->run($params);
+            return (new GameRegPayMonthDataReportLogic())->run($params);
         }
         }
 
 
         if(!empty($params["type"]) && $params["type"] == "day"){
         if(!empty($params["type"]) && $params["type"] == "day"){
-            return (new GameRegPayDayLogic())->run($params);
+            return (new GameRegPayDayDataReportLogic())->run($params);
         }
         }
 
 
         return "无执行内容";
         return "无执行内容";

+ 3 - 3
app/process/dataReport/GameTotal.php

@@ -1,7 +1,7 @@
 <?php
 <?php
 
 
 namespace app\process\dataReport;
 namespace app\process\dataReport;
-use app\v1\logic\tool\GameTotalMonthLogic;
+use app\v1\logic\tool\dataReport\GameTotalMonthDataReportLogic;
 use Workerman\Crontab\Crontab;
 use Workerman\Crontab\Crontab;
 
 
 /**
 /**
@@ -13,7 +13,7 @@ class GameTotal
     {
     {
         // 每2小时执行一次
         // 每2小时执行一次
         new Crontab('0 */2 * * *', function() {
         new Crontab('0 */2 * * *', function() {
-            (new GameTotalMonthLogic())->run();
+            (new GameTotalMonthDataReportLogic())->run();
         });
         });
     }
     }
 
 
@@ -22,6 +22,6 @@ class GameTotal
     {
     {
          $params = $args ? json_decode($args, true) : [];
          $params = $args ? json_decode($args, true) : [];
 
 
-         return (new GameTotalMonthLogic())->run($params);
+         return (new GameTotalMonthDataReportLogic())->run($params);
     }
     }
 }
 }

+ 11 - 0
app/v1/logic/advert/AgentSiteLogic.php

@@ -343,4 +343,15 @@ class AgentSiteLogic extends BaseLogic
             'wxgamepro' => $wxgamepro ?? "",
             'wxgamepro' => $wxgamepro ?? "",
         ];
         ];
     }
     }
+
+    public function getSiteAuth(): array
+    {
+        $siteList = $this->model->select();
+
+        $siteMap = [];
+        foreach ($siteList as $site) {
+            $siteMap[$site['id']] = $site;
+        }
+        return $siteMap;
+    }
 }
 }

+ 239 - 0
app/v1/logic/tool/advert/GdtCostHourLogic.php

@@ -0,0 +1,239 @@
+<?php
+
+namespace app\v1\logic\tool\advert;
+
+use app\v1\logic\advert\AgentSiteLogic;
+use GuzzleHttp\Client;
+use support\think\Db;
+
+class GdtCostHourLogic
+{
+    protected string $dateTable = "media_cost";
+
+    protected string $hourTable = "media_cost_hour";
+
+    protected string $date;
+
+    protected array $advertiserIds=[];
+
+    protected array $siteMap=[];
+
+    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'];
+        }
+
+        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();
+
+        $accountList = $this->getAccountList();
+
+        $this->siteMap = (new AgentSiteLogic())->getSiteAuth();
+        // 循环执行
+        foreach ($accountList as $account)
+        {
+            $accessToken = $tokenMap[$account['pmid']] ?? "";
+            if(!$accessToken) continue;
+
+            // 获取消耗
+            $dataList = $this->getGdtCost($account['advertiser_id'], $accessToken);
+
+            // 整理数据入库
+            $this->organizeDataList($account, $dataList);
+        }
+    }
+
+    // 获取媒体消耗
+    protected function getGdtCost($advertiser_id, $access_token): 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;
+            $request_data = [
+                'account_id' => $advertiser_id,
+                'level'      => 'REPORT_LEVEL_ADGROUP',
+                'date_range' => json_encode(['start_date' => $this->date, 'end_date' => $this->date]),
+                'group_by'   => json_encode(['hour', 'adgroup_id']),
+                'fields'     => json_encode(['hour', 'adgroup_id', 'adgroup_name', 'view_count', 'valid_click_count', 'cost', 'activated_count']),
+                'page'       => $page,
+                'page_size'  => 100,
+            ];
+            $url = $url."&".http_build_query($request_data);
+            $httpClient = new Client(['timeout' => 10]);
+            $res = $httpClient->request('GET', $url);
+            $result = json_decode($res->getBody(), true);
+
+            if (empty($result['data']['list'])) {
+                break;
+            }
+
+            $data = array_merge($data, $result['data']['list']);
+            $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) {
+            $ad_id   = $val['adgroup_id'];
+            $ad_name = $val['adgroup_name'];
+            $cost    = $val['cost']/100;
+            $show    = $val['view_count'];
+            $click   = $val['valid_click_count'];
+            $convert = $val['activated_count'];
+
+            // Todo 从广告名称中拆分归因数据
+            preg_match("/([\d]*)_([\d]*)_([\d]*)/", $ad_name, $matchs);
+            $game_id = $matchs[1] ?? 0;
+            $agent_id = $matchs[2] ?? 0;
+            $site_id = $matchs[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'   => $val['hour'],
+            ];
+
+            $data = [
+                '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) {
+                $data['id'] = $hourId;
+            }
+            // 保存小时数据
+            $db->table($this->hourTable)->save(array_merge($data, $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,
+            ];
+
+            $data = [
+                '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) {
+                $data['id'] = $dateId;
+            }
+            // 保存日数据
+            $db->table($this->dateTable)->save(array_merge($data, $where));
+        }
+    }
+
+    // 获取需要拉取消耗的媒体账户
+    protected function getAccountList(): array
+    {
+        $table = "ad_gdt_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 getTokenMap(): array
+    {
+        $table = "ad_gdt_account";
+        $where = [
+            "status" => 1
+        ];
+        return Db::connect('db_advert')->table($table)->where($where)->column("access_token", "id");
+    }
+}

+ 5 - 5
app/v1/logic/tool/BaseLogic.php → app/v1/logic/tool/dataReport/BaseDataReportLogic.php

@@ -1,25 +1,25 @@
 <?php
 <?php
 
 
-namespace app\v1\logic\tool;
+namespace app\v1\logic\tool\dataReport;
 
 
 
 
 use support\think\Db;
 use support\think\Db;
 
 
-class BaseLogic
+class BaseDataReportLogic
 {
 {
 
 
-    protected function replaceData($where): bool
+    protected function replaceData($where, $db='db_data_report'): bool
     {
     {
         // 设置归属人
         // 设置归属人
         $this->siteAuth();
         $this->siteAuth();
 
 
         // 先删除,再写入
         // 先删除,再写入
-        Db::connect('db_data_report')->table($this->table)->where($where)->delete();
+        Db::connect($db)->table($this->table)->where($where)->delete();
 
 
         // 保持每个子数组键一致,无值则填充0
         // 保持每个子数组键一致,无值则填充0
         $insertData = $this->normalizeArrayKeys($this->data);
         $insertData = $this->normalizeArrayKeys($this->data);
 
 
-        return Db::connect('db_data_report')->table($this->table)->insertAll($insertData) !== false;
+        return Db::connect($db)->table($this->table)->insertAll($insertData) !== false;
     }
     }
 
 
     protected function pushData($rows): void
     protected function pushData($rows): void

+ 13 - 7
app/v1/logic/tool/BaseTotalDayLogic.php → app/v1/logic/tool/dataReport/BaseTotalDayDataReportLogic.php

@@ -1,11 +1,12 @@
 <?php
 <?php
 
 
-namespace app\v1\logic\tool;
+namespace app\v1\logic\tool\dataReport;
+
 
 
 
 
 use support\think\Db;
 use support\think\Db;
 
 
-class BaseTotalDayLogic extends BaseLogic
+class BaseTotalDayDataReportLogic extends BaseDataReportLogic
 {
 {
     protected string $table = "base_total_day";
     protected string $table = "base_total_day";
 
 
@@ -14,11 +15,16 @@ class BaseTotalDayLogic extends BaseLogic
     protected array $data;
     protected array $data;
 
 
     protected string $date;
     protected string $date;
+
     public function run($params=[])
     public function run($params=[])
     {
     {
         if(!empty($params['date'])){
         if(!empty($params['date'])){
             $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
             $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
-            $eDate = is_array($params['date']) ? $params['date'][1] : $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{
         }else{
             $sDate = date('Y-m-d');
             $sDate = date('Y-m-d');
             $eDate = date('Y-m-d');
             $eDate = date('Y-m-d');
@@ -26,8 +32,6 @@ class BaseTotalDayLogic extends BaseLogic
 
 
         for ($date = $sDate; $date <= $eDate; $date = date('Y-m-d', strtotime($date . '+1 day'))){
         for ($date = $sDate; $date <= $eDate; $date = date('Y-m-d', strtotime($date . '+1 day'))){
             $this->date = $date;
             $this->date = $date;
-            $this->table = $this->table . "_" . date('Y', strtotime($this->date));
-
             try {
             try {
                 $this->initStart();
                 $this->initStart();
             }catch (\Exception $e){
             }catch (\Exception $e){
@@ -52,7 +56,7 @@ class BaseTotalDayLogic extends BaseLogic
         if($day==$t){
         if($day==$t){
             if($hour==1 && $i<10){
             if($hour==1 && $i<10){
                 for ($d=1; $d<=$t; $d++){
                 for ($d=1; $d<=$t; $d++){
-                    $this->date = date('Y-m-d', strtotime("-{$d} day"));
+                    $this->date = date('Y-m-d', strtotime("-{$d} days"));
                     $this->initStart();
                     $this->initStart();
                 }
                 }
             }
             }
@@ -60,7 +64,7 @@ class BaseTotalDayLogic extends BaseLogic
             // 重跑前3天
             // 重跑前3天
             if($hour==8 && $i<10){
             if($hour==8 && $i<10){
                 for ($d=1; $d<=3; $d++){
                 for ($d=1; $d<=3; $d++){
-                    $this->date = date('Y-m-d', strtotime("-{$d} day"));
+                    $this->date = date('Y-m-d', strtotime("-{$d} days"));
                     $this->initStart();
                     $this->initStart();
                 }
                 }
             }
             }
@@ -69,6 +73,8 @@ class BaseTotalDayLogic extends BaseLogic
 
 
     protected function initStart(): void
     protected function initStart(): void
     {
     {
+        $this->table = $this->table . "_" . date('Y', strtotime($this->date));
+
         // 重置数据
         // 重置数据
         $this->data = [];
         $this->data = [];
 
 

+ 13 - 5
app/v1/logic/tool/BaseTotalHourLogic.php → app/v1/logic/tool/dataReport/BaseTotalHourDataReportLogic.php

@@ -1,11 +1,12 @@
 <?php
 <?php
 
 
-namespace app\v1\logic\tool;
+namespace app\v1\logic\tool\dataReport;
+
 
 
 
 
 use support\think\Db;
 use support\think\Db;
 
 
-class BaseTotalHourLogic extends BaseLogic
+class BaseTotalHourDataReportLogic extends BaseDataReportLogic
 {
 {
     protected string $table = "base_total_hour";
     protected string $table = "base_total_hour";
     
     
@@ -14,13 +15,18 @@ class BaseTotalHourLogic extends BaseLogic
     protected array $data;
     protected array $data;
 
 
     protected string $date;
     protected string $date;
+
     protected string $hour;
     protected string $hour;
 
 
     public function run($params=[])
     public function run($params=[])
     {
     {
         if(!empty($params['date'])){
         if(!empty($params['date'])){
             $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
             $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
-            $eDate = is_array($params['date']) ? $params['date'][1] : $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);
+            }
             $runDate = 1;
             $runDate = 1;
         }else{
         }else{
             $sDate = date('Y-m-d');
             $sDate = date('Y-m-d');
@@ -28,9 +34,8 @@ class BaseTotalHourLogic extends BaseLogic
             $runDate = 0;
             $runDate = 0;
         }
         }
 
 
-        for ($date = $sDate; $date <= $eDate; $date = date('Y-m-d', strtotime($date . '+1 day'))){
+        for ($date = $sDate; $date <= $eDate; $date = date('Y-m-d', strtotime($date . '+1 days'))){
             $this->date = $date;
             $this->date = $date;
-            $this->table = $this->table . "_" . date('Ym', strtotime($this->date));
 
 
             try {
             try {
                 if($runDate){
                 if($runDate){
@@ -57,6 +62,7 @@ class BaseTotalHourLogic extends BaseLogic
     {
     {
         if (date('H') == 8 && date('i') < 10) {
         if (date('H') == 8 && date('i') < 10) {
             for ($sHour = 0; $sHour <= 23; $sHour++) {
             for ($sHour = 0; $sHour <= 23; $sHour++) {
+                $this->date = date('Y-m-d', strtotime("-1 days"));
                 $this->hour = $sHour;
                 $this->hour = $sHour;
                 $this->initStart();
                 $this->initStart();
             }
             }
@@ -65,6 +71,8 @@ class BaseTotalHourLogic extends BaseLogic
 
 
     protected function initStart(): void
     protected function initStart(): void
     {
     {
+        $this->table = $this->table . "_" . date('Ym', strtotime($this->date));
+
         // 重置数据
         // 重置数据
         $this->data = [];
         $this->data = [];
 
 

+ 13 - 7
app/v1/logic/tool/BasicActiveDayLogic.php → app/v1/logic/tool/dataReport/BasicActiveDayDataReportLogic.php

@@ -1,11 +1,12 @@
 <?php
 <?php
 
 
-namespace app\v1\logic\tool;
+namespace app\v1\logic\tool\dataReport;
+
 
 
 
 
 use support\think\Db;
 use support\think\Db;
 
 
-class BasicActiveDayLogic extends BaseLogic
+class BasicActiveDayDataReportLogic extends BaseDataReportLogic
 {
 {
     protected string $table = "basic_active_day";
     protected string $table = "basic_active_day";
 
 
@@ -18,15 +19,18 @@ class BasicActiveDayLogic extends BaseLogic
     {
     {
         if(!empty($params['date'])){
         if(!empty($params['date'])){
             $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
             $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
-            $eDate = is_array($params['date']) ? $params['date'][1] : $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{
         }else{
             $sDate = date('Y-m-d');
             $sDate = date('Y-m-d');
             $eDate = date('Y-m-d');
             $eDate = date('Y-m-d');
         }
         }
 
 
-        for ($date = $sDate; $date <= $eDate; $date = date('Y-m-d', strtotime($date . '+1 day'))){
+        for ($date = $sDate; $date <= $eDate; $date = date('Y-m-d', strtotime($date . '+1 days'))){
             $this->date = $date;
             $this->date = $date;
-            $this->table = $this->table . "_" . date('Y', strtotime($this->date));
 
 
             try {
             try {
                 $this->initStart();
                 $this->initStart();
@@ -52,7 +56,7 @@ class BasicActiveDayLogic extends BaseLogic
         if($day==$t){
         if($day==$t){
             if($hour==1 && $i<10){
             if($hour==1 && $i<10){
                 for ($d=1; $d<=$t; $d++){
                 for ($d=1; $d<=$t; $d++){
-                    $this->date = date('Y-m-d', strtotime("-{$d} day"));
+                    $this->date = date('Y-m-d', strtotime("-{$d} days"));
                     $this->initStart();
                     $this->initStart();
                 }
                 }
             }
             }
@@ -60,7 +64,7 @@ class BasicActiveDayLogic extends BaseLogic
             // 重跑前3天
             // 重跑前3天
             if($hour==8 && $i<10){
             if($hour==8 && $i<10){
                 for ($d=1; $d<=3; $d++){
                 for ($d=1; $d<=3; $d++){
-                    $this->date = date('Y-m-d', strtotime("-{$d} day"));
+                    $this->date = date('Y-m-d', strtotime("-{$d} days"));
                     $this->initStart();
                     $this->initStart();
                 }
                 }
             }
             }
@@ -69,6 +73,8 @@ class BasicActiveDayLogic extends BaseLogic
 
 
     protected function initStart(): void
     protected function initStart(): void
     {
     {
+        $this->table = $this->table . "_" . date('Y', strtotime($this->date));
+
         // 重置数据
         // 重置数据
         $this->data = [];
         $this->data = [];
 
 

+ 9 - 4
app/v1/logic/tool/GameRegPayDayLogic.php → app/v1/logic/tool/dataReport/GameRegPayDayDataReportLogic.php

@@ -1,11 +1,12 @@
 <?php
 <?php
 
 
-namespace app\v1\logic\tool;
+namespace app\v1\logic\tool\dataReport;
+
 
 
 
 
 use support\think\Db;
 use support\think\Db;
 
 
-class GameRegPayDayLogic extends BaseLogic
+class GameRegPayDayDataReportLogic extends BaseDataReportLogic
 {
 {
     protected string $table = "game_reg_pay_day";
     protected string $table = "game_reg_pay_day";
 
 
@@ -19,7 +20,11 @@ class GameRegPayDayLogic extends BaseLogic
     {
     {
         if(!empty($params['date'])){
         if(!empty($params['date'])){
             $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
             $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
-            $eDate = is_array($params['date']) ? $params['date'][1] : $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{
         }else{
             $sDate = date('Y-m-d');
             $sDate = date('Y-m-d');
             $eDate = date('Y-m-d');
             $eDate = date('Y-m-d');
@@ -27,7 +32,6 @@ class GameRegPayDayLogic extends BaseLogic
 
 
         for ($date = $sDate; $date <= $eDate; $date = date('Y-m-d', strtotime($date . '+1 days'))){
         for ($date = $sDate; $date <= $eDate; $date = date('Y-m-d', strtotime($date . '+1 days'))){
             $this->date = $date;
             $this->date = $date;
-            $this->table = $this->table . "_" . date('Y', strtotime($this->date));
 
 
             try {
             try {
                 $this->initStart();
                 $this->initStart();
@@ -57,6 +61,7 @@ class GameRegPayDayLogic extends BaseLogic
 
 
     protected function initStart(): void
     protected function initStart(): void
     {
     {
+        $this->table = $this->table . "_" . date('Y', strtotime($this->date));
         // 重置数据
         // 重置数据
         $this->data = [];
         $this->data = [];
 
 

+ 8 - 3
app/v1/logic/tool/GameRegPayMonthLogic.php → app/v1/logic/tool/dataReport/GameRegPayMonthDataReportLogic.php

@@ -1,11 +1,12 @@
 <?php
 <?php
 
 
-namespace app\v1\logic\tool;
+namespace app\v1\logic\tool\dataReport;
+
 
 
 
 
 use support\think\Db;
 use support\think\Db;
 
 
-class GameRegPayMonthLogic extends BaseLogic
+class GameRegPayMonthDataReportLogic extends BaseDataReportLogic
 {
 {
     protected string $table = "game_reg_pay_month";
     protected string $table = "game_reg_pay_month";
 
 
@@ -19,7 +20,11 @@ class GameRegPayMonthLogic extends BaseLogic
     {
     {
         if(!empty($params['date'])){
         if(!empty($params['date'])){
             $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
             $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
-            $eDate = is_array($params['date']) ? $params['date'][1] : $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{
         }else{
             $sDate = date('Y-m');
             $sDate = date('Y-m');
             $eDate = date('Y-m');
             $eDate = date('Y-m');

+ 8 - 3
app/v1/logic/tool/GameTotalMonthLogic.php → app/v1/logic/tool/dataReport/GameTotalMonthDataReportLogic.php

@@ -1,11 +1,12 @@
 <?php
 <?php
 
 
-namespace app\v1\logic\tool;
+namespace app\v1\logic\tool\dataReport;
+
 
 
 
 
 use support\think\Db;
 use support\think\Db;
 
 
-class GameTotalMonthLogic extends BaseLogic
+class GameTotalMonthDataReportLogic extends BaseDataReportLogic
 {
 {
     protected string $table = "game_total_month";
     protected string $table = "game_total_month";
 
 
@@ -18,7 +19,11 @@ class GameTotalMonthLogic extends BaseLogic
     {
     {
         if(!empty($params['date'])){
         if(!empty($params['date'])){
             $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
             $sDate = is_array($params['date']) ? $params['date'][0] : $params['date'];
-            $eDate = is_array($params['date']) ? $params['date'][1] : $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{
         }else{
             $sDate = date('Y-m');
             $sDate = date('Y-m');
             $eDate = date('Y-m');
             $eDate = date('Y-m');

+ 2 - 1
composer.json

@@ -27,7 +27,8 @@
     "php": ">=8.1",
     "php": ">=8.1",
     "workerman/webman-framework": "^2.1",
     "workerman/webman-framework": "^2.1",
     "monolog/monolog": "^2.0",
     "monolog/monolog": "^2.0",
-    "saithink/saiadmin": "^5.0"
+    "saithink/saiadmin": "^5.0",
+    "webman/console": "^2.1"
   },
   },
   "suggest": {
   "suggest": {
     "ext-event": "For better performance. "
     "ext-event": "For better performance. "

+ 396 - 3
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
         "This file is @generated automatically"
     ],
     ],
-    "content-hash": "fd85cf0ed128b514bffca0bc7c4da4d6",
+    "content-hash": "c821c6d75123e9883409054fe2de966c",
     "packages": [
     "packages": [
         {
         {
             "name": "brick/math",
             "name": "brick/math",
@@ -2412,6 +2412,100 @@
             ],
             ],
             "time": "2025-03-13T15:25:07+00:00"
             "time": "2025-03-13T15:25:07+00:00"
         },
         },
+        {
+            "name": "symfony/console",
+            "version": "v6.4.23",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/console.git",
+                "reference": "9056771b8eca08d026cd3280deeec3cfd99c4d93"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/console/zipball/9056771b8eca08d026cd3280deeec3cfd99c4d93",
+                "reference": "9056771b8eca08d026cd3280deeec3cfd99c4d93",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.1",
+                "symfony/deprecation-contracts": "^2.5|^3",
+                "symfony/polyfill-mbstring": "~1.0",
+                "symfony/service-contracts": "^2.5|^3",
+                "symfony/string": "^5.4|^6.0|^7.0"
+            },
+            "conflict": {
+                "symfony/dependency-injection": "<5.4",
+                "symfony/dotenv": "<5.4",
+                "symfony/event-dispatcher": "<5.4",
+                "symfony/lock": "<5.4",
+                "symfony/process": "<5.4"
+            },
+            "provide": {
+                "psr/log-implementation": "1.0|2.0|3.0"
+            },
+            "require-dev": {
+                "psr/log": "^1|^2|^3",
+                "symfony/config": "^5.4|^6.0|^7.0",
+                "symfony/dependency-injection": "^5.4|^6.0|^7.0",
+                "symfony/event-dispatcher": "^5.4|^6.0|^7.0",
+                "symfony/http-foundation": "^6.4|^7.0",
+                "symfony/http-kernel": "^6.4|^7.0",
+                "symfony/lock": "^5.4|^6.0|^7.0",
+                "symfony/messenger": "^5.4|^6.0|^7.0",
+                "symfony/process": "^5.4|^6.0|^7.0",
+                "symfony/stopwatch": "^5.4|^6.0|^7.0",
+                "symfony/var-dumper": "^5.4|^6.0|^7.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Console\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Eases the creation of beautiful and testable command line interfaces",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "cli",
+                "command-line",
+                "console",
+                "terminal"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/console/tree/v6.4.23"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2025-06-27T19:37:22+00:00"
+        },
         {
         {
             "name": "symfony/deprecation-contracts",
             "name": "symfony/deprecation-contracts",
             "version": "v3.6.0",
             "version": "v3.6.0",
@@ -2558,6 +2652,165 @@
             ],
             ],
             "time": "2024-09-09T11:45:10+00:00"
             "time": "2024-09-09T11:45:10+00:00"
         },
         },
+        {
+            "name": "symfony/polyfill-intl-grapheme",
+            "version": "v1.32.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+                "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe",
+                "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2"
+            },
+            "suggest": {
+                "ext-intl": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "thanks": {
+                    "url": "https://github.com/symfony/polyfill",
+                    "name": "symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for intl's grapheme_* functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "grapheme",
+                "intl",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-09-09T11:45:10+00:00"
+        },
+        {
+            "name": "symfony/polyfill-intl-normalizer",
+            "version": "v1.32.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+                "reference": "3833d7255cc303546435cb650316bff708a1c75c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c",
+                "reference": "3833d7255cc303546435cb650316bff708a1c75c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2"
+            },
+            "suggest": {
+                "ext-intl": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "thanks": {
+                    "url": "https://github.com/symfony/polyfill",
+                    "name": "symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+                },
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for intl's Normalizer class and related functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "intl",
+                "normalizer",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-09-09T11:45:10+00:00"
+        },
         {
         {
             "name": "symfony/polyfill-mbstring",
             "name": "symfony/polyfill-mbstring",
             "version": "v1.32.0",
             "version": "v1.32.0",
@@ -2802,6 +3055,92 @@
             ],
             ],
             "time": "2025-04-25T09:37:31+00:00"
             "time": "2025-04-25T09:37:31+00:00"
         },
         },
+        {
+            "name": "symfony/string",
+            "version": "v6.4.21",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/string.git",
+                "reference": "73e2c6966a5aef1d4892873ed5322245295370c6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/string/zipball/73e2c6966a5aef1d4892873ed5322245295370c6",
+                "reference": "73e2c6966a5aef1d4892873ed5322245295370c6",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.1",
+                "symfony/polyfill-ctype": "~1.8",
+                "symfony/polyfill-intl-grapheme": "~1.0",
+                "symfony/polyfill-intl-normalizer": "~1.0",
+                "symfony/polyfill-mbstring": "~1.0"
+            },
+            "conflict": {
+                "symfony/translation-contracts": "<2.5"
+            },
+            "require-dev": {
+                "symfony/error-handler": "^5.4|^6.0|^7.0",
+                "symfony/http-client": "^5.4|^6.0|^7.0",
+                "symfony/intl": "^6.2|^7.0",
+                "symfony/translation-contracts": "^2.5|^3.0",
+                "symfony/var-exporter": "^5.4|^6.0|^7.0"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "Resources/functions.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Component\\String\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "grapheme",
+                "i18n",
+                "string",
+                "unicode",
+                "utf-8",
+                "utf8"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/string/tree/v6.4.21"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2025-04-18T15:23:29+00:00"
+        },
         {
         {
             "name": "symfony/translation",
             "name": "symfony/translation",
             "version": "v6.4.22",
             "version": "v6.4.22",
@@ -3670,6 +4009,60 @@
             },
             },
             "time": "2025-03-01T08:43:36+00:00"
             "time": "2025-03-01T08:43:36+00:00"
         },
         },
+        {
+            "name": "webman/console",
+            "version": "v2.1.8",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/webman-php/console.git",
+                "reference": "2d4ce527810f91e1b4f583ec90eae24a0334ab10"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/webman-php/console/zipball/2d4ce527810f91e1b4f583ec90eae24a0334ab10",
+                "reference": "2d4ce527810f91e1b4f583ec90eae24a0334ab10",
+                "shasum": ""
+            },
+            "require": {
+                "doctrine/inflector": "^2.0",
+                "php": ">=8.1",
+                "symfony/console": ">=6.0"
+            },
+            "require-dev": {
+                "workerman/webman": "^2.1"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Webman\\Console\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "walkor",
+                    "email": "walkor@workerman.net",
+                    "homepage": "http://www.workerman.net",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Webman console",
+            "homepage": "http://www.workerman.net",
+            "keywords": [
+                "webman console"
+            ],
+            "support": {
+                "email": "walkor@workerman.net",
+                "forum": "http://www.workerman.net/questions",
+                "issues": "https://github.com/webman-php/console/issues",
+                "source": "https://github.com/webman-php/console",
+                "wiki": "http://www.workerman.net/doc/webman"
+            },
+            "time": "2025-06-02T00:42:16+00:00"
+        },
         {
         {
             "name": "webman/event",
             "name": "webman/event",
             "version": "v1.0.5",
             "version": "v1.0.5",
@@ -4088,12 +4481,12 @@
     "packages-dev": [],
     "packages-dev": [],
     "aliases": [],
     "aliases": [],
     "minimum-stability": "dev",
     "minimum-stability": "dev",
-    "stability-flags": [],
+    "stability-flags": {},
     "prefer-stable": true,
     "prefer-stable": true,
     "prefer-lowest": false,
     "prefer-lowest": false,
     "platform": {
     "platform": {
         "php": ">=8.1"
         "php": ">=8.1"
     },
     },
-    "platform-dev": [],
+    "platform-dev": {},
     "plugin-api-version": "2.6.0"
     "plugin-api-version": "2.6.0"
 }
 }

+ 24 - 0
config/plugin/webman/console/app.php

@@ -0,0 +1,24 @@
+<?php
+return [
+    'enable' => true,
+
+    'build_dir'  => BASE_PATH . DIRECTORY_SEPARATOR . 'build',
+
+    'phar_filename' => 'webman.phar',
+
+    'bin_filename' => 'webman.bin',
+
+    'signature_algorithm'=> Phar::SHA256, //set the signature algorithm for a phar and apply it. The signature algorithm must be one of Phar::MD5, Phar::SHA1, Phar::SHA256, Phar::SHA512, or Phar::OPENSSL.
+
+    'private_key_file'  => '', // The file path for certificate or OpenSSL private key file.
+
+    'exclude_pattern'   => '#^(?!.*(composer.json|/.github/|/.idea/|/.git/|/.setting/|/runtime/|/vendor-bin/|/build/|/vendor/webman/admin/))(.*)$#',
+
+    'exclude_files'     => [
+        '.env', 'LICENSE', 'composer.json', 'composer.lock', 'start.php', 'webman.phar', 'webman.bin'
+    ],
+
+    'custom_ini' => '
+memory_limit = 256M
+    ',
+];

+ 5 - 1
config/process.php

@@ -73,5 +73,9 @@ return [
     ],
     ],
     'game_total' =>  [
     'game_total' =>  [
         'handler' => \app\process\dataReport\GameTotal::class,
         'handler' => \app\process\dataReport\GameTotal::class,
-    ]
+    ],
+    // gdt 获取广告消耗
+    'gdt_cost' =>  [
+        'handler' => \app\process\advert\GdtCostHour::class,
+    ],
 ];
 ];

+ 0 - 1
plugin/saiadmin/basic/BaseLogic.php

@@ -358,7 +358,6 @@ class BaseLogic
 
 
 
 
             if(!empty($agentSiteList) ){
             if(!empty($agentSiteList) ){
-                print_r('$agentSiteList');
                 $data[$key]['site_name'] = $agentSiteList[$value['site_id']] ?? '';
                 $data[$key]['site_name'] = $agentSiteList[$value['site_id']] ?? '';
             }
             }
             if(!empty($agentList) ){
             if(!empty($agentList) ){

+ 71 - 0
webman

@@ -0,0 +1,71 @@
+#!/usr/bin/env php
+<?php
+
+use Webman\Config;
+use Webman\Console\Command;
+use Webman\Console\Util;
+use support\Container;
+use Dotenv\Dotenv;
+
+if (!Phar::running()) {
+    chdir(__DIR__);
+}
+require_once __DIR__ . '/vendor/autoload.php';
+
+if (!$appConfigFile = config_path('app.php')) {
+    throw new RuntimeException('Config file not found: app.php');
+}
+
+if (class_exists(Dotenv::class) && file_exists(run_path('.env'))) {
+    if (method_exists(Dotenv::class, 'createUnsafeImmutable')) {
+        Dotenv::createUnsafeImmutable(run_path())->load();
+    } else {
+        Dotenv::createMutable(run_path())->load();
+    }
+}
+
+$appConfig = require $appConfigFile;
+if ($timezone = $appConfig['default_timezone'] ?? '') {
+    date_default_timezone_set($timezone);
+}
+
+if ($errorReporting = $appConfig['error_reporting'] ?? '') {
+    error_reporting($errorReporting);
+}
+
+if (!in_array($argv[1] ?? '', ['start', 'restart', 'stop', 'status', 'reload', 'connections'])) {
+    require_once __DIR__ . '/support/bootstrap.php';
+} else {
+    if (class_exists('Support\App')) {
+        Support\App::loadAllConfig(['route']);
+    } else {
+        Config::reload(config_path(), ['route', 'container']);
+    }
+}
+
+$cli = new Command();
+$cli->setName('webman cli');
+$cli->installInternalCommands();
+if (is_dir($command_path = Util::guessPath(app_path(), '/command', true))) {
+    $cli->installCommands($command_path);
+}
+
+foreach (config('plugin', []) as $firm => $projects) {
+    if (isset($projects['app'])) {
+        foreach (['', '/app'] as $app) {
+            if ($command_str = Util::guessPath(base_path() . "/plugin/$firm{$app}", 'command')) {
+                $command_path = base_path() . "/plugin/$firm{$app}/$command_str";
+                $cli->installCommands($command_path, "plugin\\$firm" . str_replace('/', '\\', $app) . "\\$command_str");
+            }
+        }
+    }
+    foreach ($projects as $name => $project) {
+        if (!is_array($project)) {
+            continue;
+        }
+        $project['command'] ??= [];
+        array_walk($project['command'], [$cli, 'createCommandInstance']);
+    }
+}
+
+$cli->run();