|
@@ -0,0 +1,375 @@
|
|
|
+<?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 $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,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $newConfigLog = DB::table('jl_event_rate_config_log')
|
|
|
+ ->where(['id' => $this->configLog->id])
|
|
|
+ ->select('report_count', 'unreport_count')
|
|
|
+ ->first();
|
|
|
+ if(($newConfigLog->report_count ?? 0 ) + ($newConfigLog->unreport_count ?? 0 )) {
|
|
|
+ $currentRate = bcdiv(($newConfigLog->report_count ?? 0 ) * 100,
|
|
|
+ (($newConfigLog->report_count ?? 0 ) + ($newConfigLog->unreport_count ?? 0 )), 2);
|
|
|
+ } else {
|
|
|
+ $currentRate = 0;
|
|
|
+ }
|
|
|
+ DB::table('callback_report_charge_record')->where([
|
|
|
+ 'order_no' => $this->order->trade_no
|
|
|
+ ])->update([
|
|
|
+ '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) {
|
|
|
+ $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_unreport++;
|
|
|
+ $this->result['continue_judge'] = false;
|
|
|
+ $this->result['need_report'] = false;
|
|
|
+ $this->result['info_type'] = 'rate_filter';
|
|
|
+ $this->result['info_str'] = '比率过滤';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断当前是回传还是不回传
|
|
|
+ * @param $obj
|
|
|
+ * @param $s 传几
|
|
|
+ * @param $m 卡几
|
|
|
+ */
|
|
|
+ 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->flag_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;
|
|
|
+ if('roi_report_all' == $this->result['info_type']) {
|
|
|
+ $reportResult = $service->roiReportCharge((object)[
|
|
|
+ 'callback' => $this->trackRecord->callback
|
|
|
+ ]);
|
|
|
+ } else {
|
|
|
+ $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,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+}
|