RechargeReport.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. namespace App\Jobs\OrangeSite;
  3. use App\Modules\Callback\Models\ChannelCallbackConfig;
  4. use App\Modules\Callback\Services\CallbackBaseService;
  5. use App\Modules\OrangeSite\Services\CheckReport\EnableReportCheck;
  6. use App\Modules\OrangeSite\Services\CheckReport\OrderAlreadyReportCheck;
  7. use App\Modules\OrangeSite\Services\CheckReport\PromotionProtectCheck;
  8. use App\Modules\OrangeSite\Services\CheckReport\RechargeAmountCheck;
  9. use App\Modules\OrangeSite\Services\CheckReport\ReportRateCheck;
  10. use App\Modules\OrangeSite\Services\CheckReport\ReportRechargeTypeCheck;
  11. use App\Modules\OrangeSite\Services\OrangeSitePromotionService;
  12. use App\Modules\OrangeSite\Services\OrangeSiteRechargeReportCheckContext;
  13. use App\Modules\OrangeSite\Services\OrangeSiteReportRateService;
  14. use App\Modules\Order\Models\ReportUserChargeRecord;
  15. use App\Modules\Trace\TraceContext;
  16. use Illuminate\Bus\Queueable;
  17. use Illuminate\Contracts\Queue\ShouldQueue;
  18. use Illuminate\Foundation\Bus\Dispatchable;
  19. use Illuminate\Pipeline\Pipeline;
  20. use Illuminate\Queue\InteractsWithQueue;
  21. use Illuminate\Queue\SerializesModels;
  22. use Illuminate\Support\Facades\DB;
  23. class RechargeReport implements ShouldQueue
  24. {
  25. use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  26. public const QUEUE = '{orangeSite}.report.recharge';
  27. public const CONNECTION = 'redis_queue';
  28. public const PLATFORM = 'orange';
  29. /**
  30. * @var array
  31. * <pre>
  32. * [
  33. * 'channelId' => 'xxx, // 站点id
  34. * 'orderId' => 'xxx', // 订单id
  35. * 'uid' => 'xxx', // 充值用户uid
  36. * ]
  37. * </pre>
  38. */
  39. private $reportInfo;
  40. /**
  41. * Create a new job instance.
  42. *
  43. * @return void
  44. */
  45. public function __construct(array $reportInfo)
  46. {
  47. $this->reportInfo = $reportInfo;
  48. }
  49. /**
  50. * Execute the job.
  51. *
  52. * @return void
  53. */
  54. public function handle()
  55. {
  56. $traceContext = new TraceContext();
  57. \Log::info('[orangeSiteRechargeReport]开始回传', [
  58. 'reportInfo' => $this->reportInfo,
  59. 'traceInfo' => $traceContext->getTraceInfo()
  60. ]);
  61. $user = DB::table('users')->find(($this->reportInfo['uid'] ?? -1));
  62. $order = DB::table('orders')->where([
  63. ['id', '=', ($this->reportInfo['orderId'] ?? -1)],
  64. ['status', '=', 'PAID']
  65. ])->first();
  66. $channelCallbackConfig = ChannelCallbackConfig::where('channel_id', ($this->reportInfo['channelId'] ?? -1))
  67. ->where('platform', self::PLATFORM)->first();
  68. $channelSettingRate = OrangeSiteReportRateService::getChannelSettingReportRate($user->distribution_channel_id);
  69. $reportCheckContext = new OrangeSiteRechargeReportCheckContext($user, $order, $channelCallbackConfig,
  70. $traceContext, $channelSettingRate);
  71. try {
  72. $reportCheckContext->checkNecessaryInfo();
  73. } catch (\Exception $exception) {
  74. \Log::error('[orangeSiteRechargeReport]回传基础信息有误', [
  75. 'message' => $exception->getMessage(),
  76. 'traceInfo' => $traceContext->getTraceInfo()
  77. ]);
  78. dingTalkAlert(config('common.orangeSite.dingTalkUrl'), "[orangeSite]订单回传基础信息有误报警:\r\n" .
  79. \json_encode([
  80. 'reportInfo' => $this->reportInfo,
  81. 'message' => $exception->getMessage(),
  82. 'traceInfo' => $traceContext->getTraceInfo()
  83. ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
  84. return;
  85. }
  86. $pipes = [
  87. EnableReportCheck::class,
  88. OrderAlreadyReportCheck::class,
  89. ReportRechargeTypeCheck::class,
  90. RechargeAmountCheck::class,
  91. PromotionProtectCheck::class,
  92. ReportRateCheck::class
  93. ];
  94. $content = app(Pipeline::class)
  95. ->send($reportCheckContext)
  96. ->through($pipes)
  97. ->then(function ($content) {
  98. return $content;
  99. });
  100. $result = $content->result;
  101. \Log::info('[orangeSiteRechargeReport]回传判定结果', [
  102. 'result' => $result,
  103. 'traceInfo' => $traceContext->getTraceInfo()]);
  104. if ($result['needRecord'] ?? true) {
  105. $this->saveReportUserChargeReportInfo($reportCheckContext, $result);
  106. }
  107. if ($result['result']) {
  108. $this->reportRecharge($reportCheckContext, $result);
  109. }
  110. }
  111. private function reportRecharge(OrangeSiteRechargeReportCheckContext $reportCheckContext, array $checkResult)
  112. {
  113. $params = [
  114. 'uid' => $reportCheckContext->user->id,
  115. 'source' => 'zsy',
  116. 'amount' => $reportCheckContext->order->price ?? 0,
  117. 'link_source' => 'tiktok_event',
  118. ];
  119. $result = $this->reprotResultDeal(CallbackBaseService::directlyCharge($params));
  120. $resultContent = \json_decode(($result['content'] ?? '[]'), true);
  121. $updateInfo = [
  122. 'status' => $result['status'] ?? 0,
  123. 'request_param' => $result['request_param'] ?? '',
  124. 'updated_at' => date('Y-m-d H:i:s'),
  125. 'content' => \json_encode(array_merge($resultContent,
  126. ['log_content' => ($reportCheckContext->result['content'] ?? '')]))
  127. ];
  128. \Log::info('[orangeSiteRechargeReport]请求回传接口结果:' . ($updateInfo['status'] ? '成功' : '失败'), [
  129. 'status' => $updateInfo['status'],
  130. 'traceInfo' => $reportCheckContext->traceContext->getTraceInfo()]);
  131. DB::transaction(function () use ($reportCheckContext, $updateInfo, $checkResult, $result) {
  132. DB::table('report_user_charge_records')->where([
  133. 'order_no' => $reportCheckContext->order->trade_no,
  134. 'uid' => $reportCheckContext->order->uid,
  135. 'link_source' => $reportCheckContext->platform,
  136. ])->update($updateInfo);
  137. if (1 == $result['status']) {
  138. /**
  139. * 如果是计划保护回传成功的,只增加 orange_site_recharge_report_protect_records.current_protect_num,
  140. * 而不增加 orange_site_recharge_report_records.rate_total_num 和 orange_site_recharge_report_records.rate_success_num
  141. */
  142. if ('promotionProtect' == ($checkResult['result_ok_reason'] ?? '')) {
  143. \Log::debug('[orangeSiteRechargeReport]回传成功,增加对应计划的成功数', [
  144. 'traceInfo' => $reportCheckContext->traceContext->getTraceInfo(),
  145. 'promotionId' => $reportCheckContext->reportInfo['promotionId']]);
  146. OrangeSitePromotionService::setCurrentPromotionProtectNum($reportCheckContext->user->distribution_channel_id,
  147. $reportCheckContext->reportInfo['promotionId'],
  148. $reportCheckContext->channelCallbackConfig->eligible_count ?: 0);
  149. } else {
  150. OrangeSiteReportRateService::increaseSuccessNum($reportCheckContext->user->distribution_channel_id,
  151. $reportCheckContext->reportInfo['configRate']);
  152. }
  153. } else {
  154. if ('promotionProtect' != ($checkResult['result_ok_reason'] ?? '')) {
  155. \Log::error('[orangeSiteRechargeReport]订单回传失败', [
  156. 'traceInfo' => $reportCheckContext->traceContext->getTraceInfo()]);
  157. OrangeSiteReportRateService::increaseFailNum($reportCheckContext->user->distribution_channel_id,
  158. $reportCheckContext->reportInfo['configRate']);
  159. } else {
  160. \Log::error('[orangeSiteRechargeReport]计划保护订单回传失败', [
  161. 'traceInfo' => $reportCheckContext->traceContext->getTraceInfo()]);
  162. }
  163. }
  164. });
  165. }
  166. /**
  167. * [调用tiktok 接口回传后,数据处理逻辑]
  168. * @return [type] [description]
  169. */
  170. public function reprotResultDeal($result)
  171. {
  172. $status = 0;
  173. $content = '';
  174. $result_data = isset($result['data']) ? $result['data'] : [];
  175. if (!empty($result_data['content'])) {
  176. $content = $result_data['content'];
  177. $con_arr = json_decode($content, true);
  178. $content = json_encode($con_arr);
  179. if (isset($con_arr['code']) && 0 == $con_arr['code']) {
  180. //tiktok_event
  181. $status = 1;
  182. }
  183. }
  184. //处理请求参数
  185. $request_param = '';
  186. if (isset($result_data['query_params'])) {
  187. if (is_string($result_data['query_params'])) {
  188. $request_param = $result_data['query_params'];
  189. }
  190. if (is_array($result_data['query_params'])) {
  191. $request_param = json_encode($result_data['query_params']);
  192. }
  193. }
  194. $data = [
  195. 'status' => $status,
  196. 'request_param' => $request_param,
  197. ];
  198. if ($content) {
  199. $data['content'] = $content;
  200. }
  201. return $data;
  202. }
  203. private function saveReportUserChargeReportInfo(OrangeSiteRechargeReportCheckContext $reportCheckContext, array $result)
  204. {
  205. $data = [
  206. 'uid' => $this->reportInfo['uid'],
  207. 'config_percent' => round($reportCheckContext->reportInfo['configRate'] / 100, 4),
  208. 'report_percent' => round($reportCheckContext->reportInfo['reportRate'] / 100, 4),
  209. 'order_no' => $reportCheckContext->order->trade_no,
  210. 'timestamp' => time(),
  211. 'status' => 0,
  212. 'type' => $result['type'] ?? '',
  213. 'content' => $result['content'] ?? '',
  214. 'channel_id' => $reportCheckContext->user->distribution_channel_id,
  215. 'request_param' => '',
  216. 'link_source' => $reportCheckContext->platform,
  217. ];
  218. ReportUserChargeRecord::updateOrCreate([
  219. 'order_no' => $data['order_no'],
  220. 'uid' => $data['uid'],
  221. 'link_source' => $data['link_source'],
  222. ], $data);
  223. }
  224. }