SyncSubmitTaskService.php 8.5 KB
<?php


namespace App\Services;

use App\Exceptions\InquiryFilterException;
use App\Models\Inquiry\InquiryForm;
use App\Models\Inquiry\InquiryFormData;
use App\Models\Project\InquiryFilterConfig;
use App\Models\Project\Project;
use App\Models\SyncSubmitTask\SyncSubmitTask;
use App\Models\Visit\Visit;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Str;
use function Symfony\Component\String\s;


/**
 * Class SyncSubmitTaskService
 * @package App\Services
 * @author zbj
 * @date 2023/12/4
 */
class SyncSubmitTaskService
{
    /**
     * @param $task
     * @return mixed
     * @throws InquiryFilterException
     * @author zbj
     * @date 2023/11/28
     */
    public static function handler($task)
    {
        $data = $task['data'];
        $checkIpCountry = self::checkIpCountry($data['domain'], $data['ip'], $task['type']);

        $data['ip'] = $checkIpCountry['ip'];
        $data['country'] = $checkIpCountry['country'];
        $data['submit_at'] = $task['created_at'];
        $project = $checkIpCountry['project'];
        $data['project_id'] = $project['id'];

        //特殊处理
        if($project['id'] == 455 && !empty($data['email']) && $data['email'] == 'alb@marketingtu.org'){
            return false;
        }

        ProjectServer::useProject($project['id']);

        $action = $task['type'];
        $handler = new self();
        return $handler->$action($data);
    }


    /**
     * 询盘
     * @param $data
     * @return bool
     * @throws InquiryFilterException
     * @author zbj
     * @date 2023/12/4
     */
    public function inquiry($data)
    {

        $this->inquiryFilter($data['project_id'], $data);

        $form_id = InquiryForm::getFromId($data['data']);

        InquiryFormData::saveData($form_id, $data['domain'], $data['ip'], $data['country'], $data['referer'], $data['user_agent'], $data['submit_at'], $data['data']);

        //转化询盘
        Visit::isInquiry($data['ip']);

        return true;
    }

    /**
     * 访问
     * @param $data
     * @return bool
     * @throws \Exception
     * @author zbj
     * @date 2023/12/4
     */
    public function visit($data)
    {

        $visit_data = $data['data'];
        $visit_data['referrer_url'] = $data['data']['referrer_url']??'';
        $visit_data['device_port'] = $data['data']['device_port']??'';
        $visit_data['url'] = $data['data']['url']??'';
        $visit_data['domain'] = $data['domain']??'';
        $visit_data['ip'] = $data['ip'];
        $visit_data['country'] = $data['country'];
        $visit_data['updated_date'] = $data['submit_at']->toDateString();
        $visit_data['created_at'] = $data['submit_at'];
        Visit::saveData($visit_data);

        return true;
    }

    /**
     * 根据ip查地区
     * @param $ip
     * @return string
     * @author zbj
     * @date 2023/11/28
     */
    public static function getCountryByIp($ip){
        if(!$ip){
            return '';
        }
        $res = Http::withoutVerifying()->get('http://ip.globalso.com', ['ip' => $ip]);
        if($res->status() == 200){
            return $res->body();
        }else{
            return '';
        }
    }

    /**
     * 是否开始测试站或中国内地询盘和访问记录
     * @param $domain
     * @param $ip
     * @param $type
     * @return array
     * @throws InquiryFilterException
     * @author zbj
     * @date 2023/11/30
     */
    public static function checkIpCountry($domain, $ip, $type){
        $domain = 'https://demo.globalso.site/';
        $project = Project::getProjectByDomain($domain);
        if(empty($project)){
            throw new InquiryFilterException('项目不存在');
        }

        // 测试环境返回信息
        if (FALSE !== strpos($domain, 'globalso.site') && !$project->is_record_test_visit) {
            throw new InquiryFilterException('测试环境过滤');
        }

        if($ip == "127.0.0.1"){
            throw new InquiryFilterException('127.0.0.1过滤');
        }
        $country = self::getCountryByIp($ip);
        //访问记录才过滤是否国内
        if ($country == "中国" && !$project->is_record_china_visit && $type == SyncSubmitTask::TYPE_VISIT){
            throw new InquiryFilterException('中国内地过滤');
        }
        return [
            'project' => $project,
            'ip' => $ip,
            'country' => $country
        ];
    }


    /**
     * 询盘配置过滤
     * @author zbj
     * @date 2024/1/20
     */
    public static function inquiryFilter($project_id, $data){
        $config = InquiryFilterConfig::getCacheInfoByProjectId($project_id);
        //是否开启过滤
        if($config && $config['status']){
            //是否包含全局规则(就是project_id=1的配置)
            if($project_id != Project::DEMO_PROJECT_ID && $config['is_global_rule']){
                self::inquiryFilter(Project::DEMO_PROJECT_ID, $data);
            }
            //过滤国家
            if($config['filter_countries'] && in_array($data['country'], $config['filter_countries'])){
                throw new InquiryFilterException( '过滤国家:' . $data['country']);
            }
            //过滤ip
            if($config['black_ips']){
                $black_ips = explode("\r\n", $config['black_ips']);
                //后端获取的ip
                if(in_array($data['ip'], $black_ips)){
                    throw new InquiryFilterException( '过滤黑名单IP:' . $data['ip']);
                }
                //前端获取的ip
                if(!empty($data['data']['ip']) && in_array($data['data']['ip'], $black_ips)){
                    throw new InquiryFilterException( '过滤黑名单IP:' . $data['data']['ip']);
                }
            }
            //过滤内容
            if(!empty($data['data']['message'])) {
                //过滤内容关键字
                if ($config['filter_contents']){
                    foreach ($config['filter_contents'] as $filter_content) {
                        if (Str::contains($data['data']['message'], $filter_content)) {
                            throw new InquiryFilterException('过滤内容:' . $filter_content);
                        }
                    }
                }
                //是否允许包含链接
                if(!$config['is_allow_link']){
                    if (Str::contains($data['data']['message'], ['http://', 'https://', 'www.'])) {
                        throw new InquiryFilterException('不允许包含链接');
                    }
                }
            }
            //过滤来源
            if($config['filter_referers']){
                //只比较path路径
                $paths = array_map(function ($v){
                    return parse_url(Url::to($v), PHP_URL_PATH);
                },$config['filter_referers']);

                //后端获取的referer
                if(in_array(parse_url($data['referer'], PHP_URL_PATH), $paths)){
                    throw new InquiryFilterException( '过滤来源链接:' . $data['referer']);
                }
                //前端获取的referer
                if(!empty($data['data']['globalso-domain_host_url']) && in_array(parse_url($data['data']['globalso-domain_host_url'], PHP_URL_PATH), $paths)){
                    throw new InquiryFilterException( '过滤来源链接:' . $data['data']['globalso-domain_host_url']);
                }
            }
            //过滤邮箱
            if($config['filter_emails'] && !empty($data['data']['email'])){
                foreach ($config['filter_emails'] as $filter_email){
                    if($data['data']['email'] == $filter_email){
                        throw new InquiryFilterException( '过滤邮箱:' . $filter_email);
                    }
                }
            }
            //过滤电话
            if($config['filter_mobiles'] && !empty($data['data']['phone'])){
                foreach ($config['filter_mobiles'] as $filter_mobile){
                    if($data['data']['phone'] == $filter_mobile){
                        throw new InquiryFilterException( '过滤电话:' . $filter_mobile);
                    }
                }
            }
            //过滤姓名
            if($config['filter_names'] && !empty($data['data']['name'])){
                foreach ($config['filter_names'] as $filter_name){
                    if($data['data']['name'] == $filter_name){
                        throw new InquiryFilterException( '过滤姓名:' . $filter_name);
                    }
                }
            }
        }
        return true;
    }

}