Sfoglia il codice sorgente

巨量2.0事件回传

liuzejian 1 anno fa
parent
commit
a9561fc2bb

+ 10 - 0
app/Jobs/Callback/ReportCharge.php

@@ -2,6 +2,7 @@
 
 namespace App\Jobs\Callback;
 
+use App\Service\Callback\JLEventReportChargeService;
 use App\Service\Callback\JuliangAccountReportChargeService;
 use App\Service\Util\Support\Trace\TraceContext;
 use Illuminate\Bus\Queueable;
@@ -63,7 +64,16 @@ class ReportCharge implements ShouldQueue
                     $reportService = new JuliangAccountReportChargeService($this->info['uid'], $order, $this->info['traceInfo']);
                     $reportService->report();
                     break;
+                case 2:
+                    //巨量2.0事件回传
+                    $reportService = new JLEventReportChargeService($this->info['uid'], $order, $this->info['traceInfo']);
+                    $reportService->report();
+                    break;
             }
+        } else {
+            myLog('reportCharge')->error('end:订单不存在或订单没有推广信息', [
+                'traceInfo' => $traceContext->getTraceInfo()
+            ]);
         }
 
     }

+ 399 - 0
app/Service/Callback/JLEventReportChargeService.php

@@ -0,0 +1,399 @@
+<?php
+
+namespace App\Service\Callback;
+
+use App\Service\Callback\Tiktok\TiktokEventReportService;
+use App\Service\Util\Support\Trace\TraceContext;
+use Illuminate\Support\Facades\DB;
+
+/**
+ * 巨量2.0事件
+ */
+class JLEventReportChargeService
+{
+    private $uid;
+    /**
+     * @var TraceContext
+     */
+    private $traceContext;
+    private $order;
+    private $result;
+    private $trackRecord;
+    private $callbackConfig;
+    private $promotion;
+    private $rateConfig;
+    private $configLog;
+    public function __construct($uid, $order, $traceInfo)
+    {
+        $this->order = $order;
+        $this->uid = $uid;
+        $this->traceContext = TraceContext::newFromParent($traceInfo);
+        $this->result = [
+            'need_report' => true,
+            'config_rate' => 0,
+            'current_rate' => 0,
+            'report_success' => false,
+            'info_type' => 'ok',
+            'continue_judge' => true,
+        ];
+    }
+
+    public function report() {
+        $this->fillRanseInfo();
+        $this->fillTrackInfo();
+        $this->judgeOrderAlreadyDeal();
+        $this->judgeIsRoi();
+        $this->judgeChargeType();
+        $this->judgeChargeMoney();
+        $this->reportJuliang();
+        $this->saveRecord();
+    }
+
+    /**
+     * 判断是否roi全量回传
+     */
+    private function judgeIsRoi() {
+        if(!$this->result['need_report']) {
+            return;
+        }
+        if(1 == $this->callbackConfig->is_roi) {
+            $this->result['continue_judge'] = false;
+            $this->result['info_type'] = 'roi_report_all';
+            $this->result['info_str']  = 'roi全量上报';
+        }
+    }
+
+    private function saveRecord() {
+        if($this->result['save_record'] ?? true) {
+            $now = date('Y-m-d H:i:s');
+            $chargeRecord = DB::table('callback_report_charge_record')->where([
+                'order_no' => $this->order->trade_no
+            ])->first();
+            if(!$chargeRecord) {
+                DB::table('callback_report_charge_record')
+                    ->insert([
+                        'uid' => $this->uid,
+                        'order_id' => $this->order->id,
+                        'order_no' => $this->order->trade_no,
+                        'optimizer_uid' => $this->promotion->uid,
+                        'filter_type' => $this->result['info_type'] ?? 'ok',
+                        'filter_reason' => $this->result['info_str'] ?? '允许回传',
+                        'report_success' => intval($this->result['report_success'] ?? false),
+                        'report_result' => \json_encode($this->result['report_result'] ?? []),
+                        'report_param' => \json_encode($this->result['report_param'] ?? []),
+                        'created_at' => $now,
+                        'updated_at' => $now,
+                        'advertiser_id' => $this->trackRecord->advertiser_id ?? '',
+                        'adv_promotion_id' => $this->trackRecord->adv_promotion_id ?? '',
+                        'config_rate' => $this->result['config_rate'],
+                        'current_rate' => $this->result['current_rate'],
+                        'user_ranse_start_at' => $this->trackRecord->ranse_start_at ?? null,
+                        'order_price' => $this->order->price,
+                        'order_created_at' => $this->order->created_at,
+                        'user_ranse_ip' => $this->trackRecord->ranse_ip ?? '',
+                        'miniprogram_id' => $this->promotion->miniprogram_id,
+                        'user_ranse_id' => $this->promotion->id,
+                        'callback_type' => $this->promotion->callback_type,
+                        'callback_config_id' => $this->promotion->callback_config_id,
+                        'ext_a' => $this->configLog->callback_param ?? '',
+                    ]);
+            } else {
+                DB::table('callback_report_charge_record')
+                    ->where(['id' => $chargeRecord->id])
+                    ->update([
+                        'uid' => $this->uid,
+                        'order_id' => $this->order->id,
+                        'order_no' => $this->order->trade_no,
+                        'optimizer_uid' => $this->promotion->uid,
+                        'filter_type' => $this->result['info_type'] ?? 'ok',
+                        'filter_reason' => $this->result['info_str'] ?? '允许回传',
+                        'report_success' => intval($this->result['report_success'] ?? false),
+                        'report_result' => \json_encode($this->result['report_result'] ?? []),
+                        'report_param' => \json_encode($this->result['report_param'] ?? []),
+                        'updated_at' => $now,
+                        'advertiser_id' => $this->trackRecord->advertiser_id ?? '',
+                        'adv_promotion_id' => $this->trackRecord->adv_promotion_id ?? '',
+                        'config_rate' => $this->result['config_rate'],
+                        'current_rate' => $this->result['current_rate'],
+                        'user_ranse_start_at' => $this->trackRecord->ranse_start_at ?? null,
+                        'order_price' => $this->order->price,
+                        'order_created_at' => $this->order->created_at,
+                        'user_ranse_ip' => $this->trackRecord->ranse_ip ?? '',
+                        'miniprogram_id' => $this->promotion->miniprogram_id,
+                        'user_ranse_id' => $this->promotion->id,
+                        'callback_type' => $this->promotion->callback_type,
+                        'callback_config_id' => $this->promotion->callback_config_id,
+                        'ext_a' => $this->configLog->callback_param ?? '',
+                    ]);
+            }
+
+            if($this->configLog) {
+                if('ok' == $this->result['info_type'] && $this->result['report_success']) {
+                    DB::table('jl_event_rate_config_log')
+                        ->where(['id' => $this->configLog->id])
+                        ->update([
+                            'report_count' => $this->configLog->report_count + 1,
+                            'updated_at' => $now,
+                        ]);
+                    if(3 == $this->configLog->callback_type) {
+                        DB::table('jl_event_rate_config_log')
+                            ->where(['id' => $this->configLog->id])
+                            ->update([
+                                'flag' => $this->configLog->flag,
+                                'flag_report' => $this->configLog->flag_report,
+                                'flag_unreport' => $this->configLog->flag_unreport,
+                                'updated_at' => $now,
+                            ]);
+                    }
+                } elseif ('rate_filter' == $this->result['info_type']) {
+                    DB::table('jl_event_rate_config_log')
+                        ->where(['id' => $this->configLog->id])
+                        ->update([
+                            'unreport_count' => $this->configLog->unreport_count + 1,
+                            'updated_at' => $now,
+                        ]);
+                    if(3 == $this->configLog->callback_type) {
+                        DB::table('jl_event_rate_config_log')
+                            ->where(['id' => $this->configLog->id])
+                            ->update([
+                                'flag' => $this->configLog->flag,
+                                'flag_report' => $this->configLog->flag_report,
+                                'flag_unreport' => $this->configLog->flag_unreport,
+                                'updated_at' => $now,
+                            ]);
+                    }
+                }
+
+
+            }
+        }
+    }
+
+    /**
+     * 判断回传比例
+     */
+    private function judgeCallbackRate(){
+        if(!$this->result['need_report']) {
+            return;
+        }
+        if(!$this->result['continue_judge']) {
+            return;
+        }
+
+        $this->rateConfig = DB::table('juliang_account_rate_config_log')
+            ->where(['company_uid' => $this->promotion->uid,
+                'account_id' => $this->trackRecord->advertiser_id, 'is_enabled' => 1])
+            ->first();
+        if(!$this->rateConfig) {
+            $this->result['need_report'] = false;
+            $this->result['info_type'] = 'no_rate_config';
+            $this->result['info_str'] = '没有可用的回传比率设置';
+            return;
+        }
+        $configRate = $this->rateConfig->config_per;
+        if(0 == $configRate) {
+            $this->result['need_report'] = false;
+            $this->result['info_type'] = 'rate_eq_0';
+            $this->result['info_str'] = '设定比例为0不执行回传';
+            return;
+        }
+        $currentTotalCount = $this->rateConfig->total_count;
+        $currentReportCount = $this->rateConfig->report_count;
+        if(0 == $currentTotalCount) {
+            $currentRate = 0;
+        } else {
+            $currentRate = min(1, round($currentReportCount / $currentTotalCount, 4)) * 100;
+        }
+        if($currentRate <= $configRate) {
+            $this->result['need_report'] = true;
+            $this->result['config_rate'] = $configRate;
+            $this->result['current_rate'] = $currentRate;
+        } else {
+            $this->result['need_report'] = false;
+            $this->result['info_type'] = 'rate_filter';
+            $this->result['info_str'] = '比率过滤';
+            $this->result['config_rate'] = $configRate;
+            $this->result['current_rate'] = $currentRate;
+        }
+    }
+
+    /**
+     * 判断订单是不是已经处理过了.如果处理过了,就不入库
+     */
+    private function judgeOrderAlreadyDeal() {
+        if(!$this->result['need_report']) {
+            return;
+        }
+        if(DB::table('callback_report_charge_record')
+            ->where(['order_id'  => $this->order->id])
+            ->exists()) {
+            $this->result['need_report'] = false;
+            $this->result['save_record'] = false;
+            $this->result['info_type'] = 'order_exists';
+            $this->result['info_str'] = '订单已经处理';
+        }
+    }
+
+    /**
+     * 判断充值的金额区间
+     */
+    private function judgeChargeMoney() {
+        if(!$this->result['need_report'] || !$this->result['continue_judge']) {
+            return;
+        }
+
+        $this->configLog = DB::table('jl_event_rate_config_log')
+            ->where([
+                'user_id' => $this->promotion->uid,
+                'config_id' => $this->callbackConfig->id,
+                'is_enabled' => 1,
+            ])->where('min_money', '<=', $this->order->price)
+            ->where('max_money', '>', $this->order->price)
+            ->orderBy('id', 'desc')
+            ->first();
+        if(!$this->configLog) {
+            $this->result['need_report'] = false;
+            $this->result['continue_judge'] = false;
+            $this->result['info_type'] = 'money_filter';
+            $this->result['info_str'] = '订单金额不在所有金额项区间内';
+            return;
+        } else {
+            if(1 == $this->configLog->callback_type) {
+                $this->result['continue_judge'] = false;
+            }elseif(2 == $this->configLog->callback_type) {
+                $this->result['continue_judge'] = false;
+                $this->result['need_report'] = false;
+                $this->result['info_type'] = 'money_filter';
+                $this->result['info_str'] = sprintf('订单金额在区间:[%s元-%s元]全部不回传',
+                    $this->configLog->min_money, $this->configLog->max_money);
+                return;
+            } elseif (3 == $this->configLog->callback_type) {
+                // ToDo,检测传几卡几
+                $sm = explode(':', $this->configLog->callback_param);
+                $this->chuanNkaM($this->configLog, $sm[0], $sm[1]);
+                if($this->configLog->flag) {
+                    $this->configLog->flag_report++;
+                } else {
+                    $this->configLog->flag_unport++;
+                    $this->result['continue_judge'] = false;
+                    $this->result['need_report'] = false;
+                    $this->result['info_type'] = 'rate_filter';
+                    $this->result['info_str'] = sprintf('当前配置传%s卡%s,本轮已传:%s,已卡%s', $sm[0], $sm[1],
+                    $this->configLog->flag_report, $this->configLog->flag_unport);
+                }
+            }
+        }
+    }
+
+    private function chuanNkaM($obj, $s, $m)
+    {
+        if($obj->flag) {
+            if(($obj->flag_report)  < $s){
+                $obj->flag = 1;
+            } else {
+                $obj->flag_report = 0;
+                $obj->flag = 0;
+            }
+        } else {
+            if(($obj->unreport) < $m) {
+                $obj->flag = 0;
+            } else {
+                $obj->flag_unreport = 0;
+                $obj->flag = 1;
+            }
+        }
+    }
+
+    /**
+     * 判断充值行为
+     */
+    private function judgeChargeType() {
+        if(!$this->result['need_report'] || !$this->result['continue_judge']) {
+            return;
+        }
+
+        if(1 == $this->callbackConfig->charge_type) {
+            $isFirstCharge = DB::table('orders')
+                    ->where([
+                        'uid' => $this->uid,
+                        'status' => 'paid',
+                        'promotion_id' => $this->trackRecord->ranse_id,
+                    ])->where('created_at', '>=', $this->trackRecord->ranse_start_at)
+                    ->where('created_at', '<=', $this->trackRecord->ranse_end_at)
+                    ->where('id', '<', $this->order->id)
+                    ->count() == 0;
+            if(!$isFirstCharge) {
+                $this->result['need_report'] = false;
+                $this->result['continue_judge'] = false;
+                $this->result['info_type'] = 'neq_first_charge';
+                $this->result['info_str'] = '非首充';
+            }
+        }
+    }
+
+    /**
+     * 获取订单的染色信息,回传配置信息, 推广被禁用,就按照没有回传配置处理
+     */
+    private function fillRanseInfo() {
+        $ranseId = $this->order->promotion_id;
+        $this->promotion = DB::table('promotions')->where('id', $ranseId)->first();
+        if(0 == $this->promotion->status || $this->promotion->callback_config_id < 1) {
+            $this->result['need_report'] = false;
+            $this->result['info_type'] = 'no_callback_config';
+            $this->result['info_str'] = '没有回传配置';
+            return;
+        }
+        $this->callbackConfig = DB::table('jl_event_callback_config')
+            ->where(['id' => $this->promotion->callback_config_id])
+            ->first();
+        if(!$this->callbackConfig) {
+            $this->result['need_report'] = false;
+            $this->result['info_type'] = 'no_callback_config';
+            $this->result['info_str'] = '没有回传配置';
+            return;
+        }
+
+    }
+    private function reportJuliang() {
+        if(!$this->result['need_report']) {
+            return;
+        }
+        $service = new TiktokEventReportService;
+        $reportResult = $service->reportCharge((object)[
+            'callback' => $this->trackRecord->callback
+        ]);
+        $reportContent = \json_decode($reportResult['content'], true);
+        if($reportResult['result']  && 0 == $reportContent['code']) {
+            $this->result['report_success'] = true;
+        } else {
+            $this->result['report_success'] = false;
+        }
+        $this->result['report_result'] = $reportResult;
+        $this->result['need_report'] = false;
+    }
+
+    /**
+     * 获取匹配的广告用户信息,主要是获取回传 callback
+     */
+    private function fillTrackInfo() {
+        if(!$this->result['need_report']) {
+            return;
+        }
+        $this->trackRecord = DB::table('callback_report_ranse_record')
+            ->where(['uid' => $this->uid, 'ranse_id' => $this->order->promotion_id])
+            ->where('ranse_start_at', '<=', $this->order->created_at)
+            ->where('ranse_end_at', '>=', $this->order->created_at)
+            ->orderBy('id', 'desc')
+            ->first();
+        if(!$this->trackRecord) {
+            $this->result['need_report'] = false;
+            $this->result['info_type'] = 'no_track_info';
+            $this->result['info_str'] = '无匹配用户';
+            return;
+        }
+
+        $this->result['report_param'] = [
+            'callback' => $this->trackRecord->callback,
+        ];
+    }
+}

+ 6 - 0
app/Service/Callback/JuliangAccountReportChargeService.php

@@ -105,6 +105,9 @@ class JuliangAccountReportChargeService
                         'order_created_at' => $this->order->created_at,
                         'user_ranse_ip' => $this->trackRecord->ranse_ip ?? '',
                         'miniprogram_id' => $this->promotion->miniprogram_id,
+                        'user_ranse_id' => $this->promotion->id,
+                        'callback_type' => $this->promotion->callback_type,
+                        'callback_config_id' => $this->promotion->callback_config_id,
                     ]);
             } else {
                 DB::table('callback_report_charge_record')
@@ -129,6 +132,9 @@ class JuliangAccountReportChargeService
                         'order_created_at' => $this->order->created_at,
                         'user_ranse_ip' => $this->trackRecord->ranse_ip ?? '',
                         'miniprogram_id' => $this->promotion->miniprogram_id,
+                        'user_ranse_id' => $this->promotion->id,
+                        'callback_type' => $this->promotion->callback_type,
+                        'callback_config_id' => $this->promotion->callback_config_id,
                     ]);
             }
 

+ 55 - 0
tests/Service/Callback/JLEventReportChargeServiceTest.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace Tests\Service\Callback;
+
+use App\Service\Callback\JLEventReportChargeService;
+use PHPUnit\Framework\TestCase;
+
+class JLEventReportChargeServiceTest extends \Tests\TestCase
+{
+    public function  testRate() {
+        $report = 0;
+        $unreport = 0;
+        $sm = explode(':', '1:4');
+        $s = $sm[0];
+        $m = $sm[1];
+
+        $obj = (object)[
+            'f' => true,
+            'report' => 0,
+            'unreport' => 0,
+        ];
+
+        foreach (range(1, 35) as $i) {
+            $this->insertR($obj, $s, $m);
+            if($obj->f) {
+                dump('回传');
+                $obj->report++;
+            } else {
+                dump('不回传');
+                $obj->unreport++;
+            }
+//            dump($obj);
+        }
+
+
+    }
+
+    public function insertR($obj, $s, $m) {
+        if($obj->f) {
+            if(($obj->report)  < $s){
+                $obj->f = true;
+            } else {
+                $obj->report = 0;
+                $obj->f = false;
+            }
+        } else {
+            if(($obj->unreport) < $m) {
+                $obj->f = false;
+            } else {
+                $obj->unreport = 0;
+                $obj->f = true;
+            }
+        }
+    }
+}