postInquiry.php 12.0 KB
<?php
namespace App\Console\Commands\Inquiry;

use App\Models\Inquiry\ReInquiryCount;
use App\Models\Inquiry\ReInquiryDetail;
use App\Models\Inquiry\ReInquiryDetailLog;
use App\Models\Inquiry\ReInquiryForm;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

/**
 * Class postInquiry
 * @package App\Console\Commands\Inquiry
 */
class postInquiry extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'post_inquiry';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '执行询盘请求';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }


    public function handle()
    {
        while (true) {
            $list = ReInquiryDetailLog::where('status', ReInquiryDetailLog::STATUS_INIT)->where('start_at', '<=', date('Y-m-d H:i:s'))->orderBy('id', 'asc')->limit(100)->get();
            if (!$list->count()){
                sleep(1);
            }
            // 询盘数据入库
            foreach ($list as $key => $val) {
                //加个锁 避免重复执行
                $lockKey = 're_inquiry_detail_log_lock_' . $val->id;
                if(!Redis::setnx($lockKey, 1)){
                    continue;
                }
                Redis::expire($lockKey, 60);

                $log = ReInquiryDetailLog::find($val->id);
                if($log->status != ReInquiryDetailLog::STATUS_INIT){
                    continue;
                }

                $this->output('开始执行' . $val->id);
                try {
                    $detail = ReInquiryDetail::find($val['detail_id']);

                    //防止 程序中断 启动时 同一时间一下就发了
                    $last_log = ReInquiryDetailLog::where('detail_id', $val['detail_id'])->where('id', '<', $val['id'])->orderBy('id', 'desc')->first();
                    //不是第一个 或者 上一个处理失败了  直接处理
                    if(!empty($last_log)){
                        //上一个还没有处理 直接跳过
                        if($last_log->status == ReInquiryDetailLog::STATUS_INIT){
                            continue;
                        }
                        //上一个处理完成
                        if($last_log->status == ReInquiryDetailLog::STATUS_SUCCESS){
                            //上次处理时间间隔达到没
                            $interval = strtotime($val->start_at) - strtotime($last_log->start_at);
                            if(time() - strtotime($last_log->updated_at) < $interval){
                                continue;
                            }
                        }
                    }

                    if($val['type'] == 1){
                        $this->visit($detail, $val);
                    }else{
                        $res = $this->inquiry($detail, $val);

                        //转发详情
                        $detail->status = $res ? ReInquiryDetail::STATUS_SUCCESS : ReInquiryDetail::STATUS_FAIL;
                        $detail->result = $val['url'];
                        $detail->save();
                        //转发表单
                        if($res){
                            $form = ReInquiryForm::find($detail['form_id']);
                            $form->success_num = $form->success_num + 1;
                            $form->save();
                            Log::channel('inquiry_relay')->info('询盘成功:',[$detail['form_id'], $val->id, getmypid()]);
                        }
                    }
                }catch (\Exception $e){
                    Log::channel('inquiry_relay')->error('inquiry_relay handle error', [$e->getMessage(), $e->getFile(), $e->getLine()]);

                    $val->status = ReInquiryDetailLog::STATUS_FAIL;
                    $val->remark = mb_substr($e->getMessage(), 0, 200);
                    $val->save();
                }
            }
        }
    }

    public function visit(ReInquiryDetail $detail, ReInquiryDetailLog $log){
        $website = 'https://' . $detail['re_website'] . '/';
        if($detail['is_v6']) {
            $data = [
                'ip' => $detail['ip'],
                'url' => $log['url'],
                'device_port' => $detail['device_port'],
                'referrer_url' => $detail['referrer'],
                'user_agent' => $detail['user_agent'],
            ];
            $res = Http::withoutVerifying()->timeout(30)->post($website . 'api/traffic_visit/', $data)->json();
            if (empty($res['status']) || $res['status'] != 200) {
                $log->status = ReInquiryDetailLog::STATUS_FAIL;
                $log->remark = mb_substr($res['message'] ?? '', 0, 200);
                $log->save();

                Log::channel('inquiry_relay')->error('inquiry_relay visit error', [$res, $website . 'api/traffic_visit/',$data]);
                return false;
            }
        }else{
            //v4 v5分离项目 往测试链接推
            $split_api_cache_key = 'quanqiusou_split_site_array';
            $site_array = Cache::get($split_api_cache_key);
            if(!$site_array){
                $client = new \GuzzleHttp\Client();
                $site_array = $client->request('GET', "https://www.quanqiusou.cn/extend_api/saas/split.php", [
                    'proxy' => env('CURL_PROXY'), // 代理服务器地址和端口号
                ])->getBody()->getContents();
                $site_array = json_decode($site_array, true);
                Cache::put($split_api_cache_key, $site_array, 7200);
            }
            $mail_urls = array_column($site_array, 'main_url');
            $key = array_search($website, $mail_urls);
            if ($key !== false) {
                // 分离项目 推送到测试链接
                $website = $site_array[$key]['test_url'];
            }

            $data = [
                'action' => 'stats_init',
                'assort' => 0,
                'referrer' => $detail['referrer'],
                'currweb' => $log['url'],
                'user_agent' => $detail['user_agent'],
                "ip" => $detail['ip'],
            ];
            $res = Http::get($website . 'wp-admin/admin-ajax.php', $data);
            $status = $res->status();
            if($status != 200){
                $log->status = ReInquiryDetailLog::STATUS_FAIL;
                $log->remark = mb_substr($res->body() ?? '', 0 ,200);
                $log->save();

                Log::channel('inquiry_relay')->error('inquiry_relay v4|v5 visit error', [$res->body(), $website . 'wp-admin/admin-ajax.php', $data]);
                return false;
            }
        }
        $log->status = ReInquiryDetailLog::STATUS_SUCCESS;
        $log->save();
        return true;
    }

    public function inquiry(ReInquiryDetail $detail, ReInquiryDetailLog $log){
        $res = false;
        if ($detail['type'] == 1) {
            // v6
            if ($detail['is_v6']) {
                $res = $this->v6Inquiry($detail, $log);
            } else {
                $res = $this->v5Inquiry($detail, $log);
            }
        } elseif ($detail['type'] == 2) {
            //商城询盘
            $res = $this->ShopInquiry($detail, $log);
        } elseif ($detail['type'] == 3) {
            //Fob询盘
            $res = $this->FobInquiry($detail, $log);
        }

        if(!$res){
            return false;
        }

        $log->status = ReInquiryDetailLog::STATUS_SUCCESS;
        $log->save();

        //统计
        ReInquiryCount::addInquiryNum($detail['id'], $detail['re_website']);

        return true;
    }

    public function v6Inquiry($detail, $log){
        $website = 'https://' . $detail['re_website'] . '/';
        $data = [
            'name' => $detail['name'],
            'phone' => $detail['phone'],
            'message' => $detail['message'],
            'submit_ip' => $detail['ip'],
            'refer' => $log->url,
        ];
        if ($detail->email) {
            $data['email'] = $detail->email;
        } else {
            $data['__amp_source_origin'] = trim($website, '/');
        }
        $res = Http::withoutVerifying()->timeout(30)->withHeaders(['User-Agent' => $detail['user_agent']])->post($website . 'api/inquiryQd?source=5', $data)->json();
        if (empty($res['code']) || $res['code'] != 200) {
            $log->status = ReInquiryDetailLog::STATUS_FAIL;
            $log->remark = mb_substr($res['message'] ?? '', 0, 200);
            $log->save();
            Log::channel('inquiry_relay')->error('inquiry_relay v6 inquiry error', [$res, $website . 'api/inquiryQd/', $data]);
            return false;
        }
        return true;
    }

    public function v5Inquiry($detail, $log){
        $data = [
            'name' => $detail['name'],
            'phone' => $detail['phone'],
            'message' => $detail['message'],
            'email' => $detail['email'],
            'ip' => $detail['ip'],
            'token' => md5($log->url . $detail['name'] . $detail['ip'] . date("Y-m-d")),
            'refer' => $log->url,
            'submit_time' => date('Y-m-d H:i:s'),
            'source' => 5,
        ];

        $result = Http::withoutVerifying()->timeout(30)->post('https://www.globalso.site/api/external-interface/add/fa043f9cbec6b38f', $data);
        $res = $result->json();
        //兼容接口返回格式
        if (!empty($res['data'][0]['status'])) {
            $res['data'][0]['code'] = $res['data'][0]['status'] == 'success' ? 200 : 400;
            !empty($res['data'][0]['msg']) && $res['message'] = $res['data'][0]['msg'];
        }
        if (empty($res['data'][0]['code']) || !in_array($res['data'][0]['code'], [200, 300])) {
            $log->status = ReInquiryDetailLog::STATUS_FAIL;
            $log->remark = mb_substr($res['message'] ?? '', 0, 200);
            $log->save();

            Log::channel('inquiry_relay')->error('inquiry_relay v4|v5 inquiry error', [$result->body(), 'https://www.globalso.site/api/external-interface/add/fa043f9cbec6b38f', $data]);
            return false;
        }
        return true;
    }

    public function ShopInquiry($detail, $log){
        $data = [
            'name' => $detail['name'],
            'email' => $detail['email'],
            'phone' => $detail['phone'],
            'message' => $detail['message'],
            'submit_ip' => $detail['ip'],
            'refer' =>  $log['url'],
        ];
        ksort($data);
        $data['token'] = md5( json_encode($data, JSON_UNESCAPED_UNICODE ) . date("Y-m-d"));
        $url = 'https://' . $detail['re_website'] . '/index.php?route=api/ai_inquiry/add';
        $res = Http::withoutVerifying()->timeout(30)->post($url, $data)->json();
        if (empty($res['code']) || $res['code'] != 200) {
            $log->status = ReInquiryDetailLog::STATUS_FAIL;
            $log->remark = mb_substr($res['message'] ?? '', 0, 200);
            $log->save();

            Log::channel('inquiry_relay')->error('inquiry_relay shop inquiry error', [$res, $url, $data]);
            return false;
        }
    }

    public function FobInquiry($detail, $log){
        $data = [
            'name' => $detail['name'],
            'email' => $detail['email'],
            'phone' => $detail['phone'],
            'post_id' => $log['url'],
            'message' => $detail['message'],
        ];
        $res = Http::withoutVerifying()->timeout(30)->post('https://fob.ai.cc/api/ad_to_scrm', $data)->json();
        if (empty($res['status']) || $res['status'] != 200) {
            $log->status = ReInquiryDetailLog::STATUS_FAIL;
            $log->remark = mb_substr($res['message'] ?? '', 0, 200);
            $log->save();

            Log::channel('inquiry_relay')->error('inquiry_relay fob inquiry error', [$res, 'https://fob.ai.cc/api/ad_to_scrm', $data]);
            return false;
        }
    }

    public function output($message)
    {
        echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
    }
}