正在显示
11 个修改的文件
包含
617 行增加
和
6 行删除
app/Console/Commands/SyncSubmitTask.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Console\Commands; | ||
| 4 | + | ||
| 5 | + | ||
| 6 | +use App\Exceptions\InquiryFilterException; | ||
| 7 | +use App\Services\SyncSubmitTaskService; | ||
| 8 | +use Illuminate\Console\Command; | ||
| 9 | +use App\Models\SyncSubmitTask\SyncSubmitTask as SyncSubmitTaskModel; | ||
| 10 | +use Illuminate\Support\Facades\Redis; | ||
| 11 | +use Illuminate\Support\Str; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * | ||
| 15 | + * Class SyncSubmitTask | ||
| 16 | + * @package App\Console\Commands | ||
| 17 | + * @author zbj | ||
| 18 | + * @date 2023/11/28 | ||
| 19 | + */ | ||
| 20 | +class SyncSubmitTask extends Command | ||
| 21 | +{ | ||
| 22 | + | ||
| 23 | + protected $signature = 'sync_submit_task'; | ||
| 24 | + protected $description = '询盘、访问异步任务'; | ||
| 25 | + | ||
| 26 | + public function handle() | ||
| 27 | + { | ||
| 28 | + while (true) { | ||
| 29 | + $task_id = $this->getTaskId(); | ||
| 30 | + if (empty($task_id)) { | ||
| 31 | + sleep(5); | ||
| 32 | + continue; | ||
| 33 | + } | ||
| 34 | + $this->output('任务' . $task_id . '开始'); | ||
| 35 | + $task_info = SyncSubmitTaskModel::find($task_id); | ||
| 36 | + if (empty($task_info) || $task_info->status) { | ||
| 37 | + $this->output('任务不存在或者已执行'); | ||
| 38 | + continue; | ||
| 39 | + } | ||
| 40 | + try { | ||
| 41 | + SyncSubmitTaskService::handler($task_info); | ||
| 42 | + $task_info->status = 1; | ||
| 43 | + $task_info->save(); | ||
| 44 | + | ||
| 45 | + $this->output('任务完成'); | ||
| 46 | + } catch (InquiryFilterException $e){ | ||
| 47 | + $task_info->status = 1; | ||
| 48 | + $task_info->is_filtered = 1; | ||
| 49 | + $task_info->remark = $e->getMessage(); | ||
| 50 | + $task_info->save(); | ||
| 51 | + | ||
| 52 | + $this->output('任务完成'); | ||
| 53 | + } catch (\Exception $e) { | ||
| 54 | + $task_info->retry = $task_info->retry + 1; | ||
| 55 | + if ($task_info->retry >= 3) { | ||
| 56 | + $task_info->status = 2; | ||
| 57 | + $task_info->remark = Str::substr($e->getMessage(), 0, 200); | ||
| 58 | + } else { | ||
| 59 | + Redis::lpush('sync_submit_task', $task_id); | ||
| 60 | + } | ||
| 61 | + $task_info->save(); | ||
| 62 | + | ||
| 63 | + $this->output('任务失败:' . $e->getMessage()); | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + public function getTaskId(){ | ||
| 69 | + $task_id = Redis::rpop('sync_submit_task'); | ||
| 70 | + if (empty($task_id)) { | ||
| 71 | + $ids = SyncSubmitTaskModel::where('status', 0)->pluck('id'); | ||
| 72 | + foreach($ids as $id){ | ||
| 73 | + Redis::lpush('sync_submit_task', $id); | ||
| 74 | + } | ||
| 75 | + $task_id = Redis::rpop('sync_submit_task'); | ||
| 76 | + } | ||
| 77 | + return $task_id; | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + /** | ||
| 81 | + * 输出处理日志 | ||
| 82 | + */ | ||
| 83 | + public function output($message): bool | ||
| 84 | + { | ||
| 85 | + echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL; | ||
| 86 | + return true; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | +} |
app/Exceptions/InquiryFilterException.php
0 → 100644
| @@ -124,4 +124,36 @@ class FormGlobalsoApi | @@ -124,4 +124,36 @@ class FormGlobalsoApi | ||
| 124 | } | 124 | } |
| 125 | return $res; | 125 | return $res; |
| 126 | } | 126 | } |
| 127 | + | ||
| 128 | + /** | ||
| 129 | + * 提交询盘 | ||
| 130 | + * @param $ip | ||
| 131 | + * @param $referer | ||
| 132 | + * @param $submit_at | ||
| 133 | + * @param $data | ||
| 134 | + * @return array|false|mixed | ||
| 135 | + * @author zbj | ||
| 136 | + * @date 2024/1/20 | ||
| 137 | + */ | ||
| 138 | + public function submitInquiry($ip, $referer, $submit_at, $data) | ||
| 139 | + { | ||
| 140 | + $api_url = $this->url . '/api/external-interface/add/fa043f9cbec6b38f'; | ||
| 141 | + | ||
| 142 | + $data['ip'] = $ip; | ||
| 143 | + $data['token'] = md5($referer . $data['name'] . $ip . date("Y-m-d")); | ||
| 144 | + $data['refer'] = $referer; | ||
| 145 | + $data['submit_time'] = date('Y-m-d H:i:s', strtotime($submit_at)); | ||
| 146 | + $data['source'] = 1; //固定 | ||
| 147 | + | ||
| 148 | + try { | ||
| 149 | + $res = HttpUtils::post($api_url, $data); | ||
| 150 | + $res = Arr::s2a($res); | ||
| 151 | + } catch (\Exception | GuzzleException $e) { | ||
| 152 | + errorLog('提交询盘信息失败', $data, $e); | ||
| 153 | + return false; | ||
| 154 | + } | ||
| 155 | + return $res; | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + | ||
| 127 | } | 159 | } |
| @@ -36,6 +36,7 @@ use App\Models\Task\Task; | @@ -36,6 +36,7 @@ use App\Models\Task\Task; | ||
| 36 | use App\Services\ProjectServer; | 36 | use App\Services\ProjectServer; |
| 37 | use Hashids\Hashids; | 37 | use Hashids\Hashids; |
| 38 | use App\Models\User\User as UserModel; | 38 | use App\Models\User\User as UserModel; |
| 39 | +use Illuminate\Support\Facades\Cache; | ||
| 39 | use Illuminate\Support\Facades\DB; | 40 | use Illuminate\Support\Facades\DB; |
| 40 | use Illuminate\Support\Facades\Http; | 41 | use Illuminate\Support\Facades\Http; |
| 41 | use Illuminate\Support\Facades\Schema; | 42 | use Illuminate\Support\Facades\Schema; |
| @@ -337,6 +338,8 @@ class ProjectLogic extends BaseLogic | @@ -337,6 +338,8 @@ class ProjectLogic extends BaseLogic | ||
| 337 | $model->edit($config,['project_id'=>$config['project_id']]); | 338 | $model->edit($config,['project_id'=>$config['project_id']]); |
| 338 | } | 339 | } |
| 339 | 340 | ||
| 341 | + Cache::forget(InquiryFilterConfig::cacheKey($config['project_id'])); | ||
| 342 | + | ||
| 340 | return $this->success(); | 343 | return $this->success(); |
| 341 | } | 344 | } |
| 342 | 345 |
| @@ -44,12 +44,6 @@ class InquiryForm extends Base | @@ -44,12 +44,6 @@ class InquiryForm extends Base | ||
| 44 | return $map; | 44 | return $map; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | - | ||
| 48 | - public function getFieldAttribute($value) | ||
| 49 | - { | ||
| 50 | - return json_decode($value, true); | ||
| 51 | - } | ||
| 52 | - | ||
| 53 | /** | 47 | /** |
| 54 | * @author zbj | 48 | * @author zbj |
| 55 | * @date 2023/12/5 | 49 | * @date 2023/12/5 |
| @@ -63,4 +57,51 @@ class InquiryForm extends Base | @@ -63,4 +57,51 @@ class InquiryForm extends Base | ||
| 63 | } | 57 | } |
| 64 | return $field; | 58 | return $field; |
| 65 | } | 59 | } |
| 60 | + | ||
| 61 | + /** | ||
| 62 | + * 根据提交数据的key获取表单id | ||
| 63 | + * @param $data | ||
| 64 | + * @return mixed | ||
| 65 | + * @author zbj | ||
| 66 | + * @date 2023/12/4 | ||
| 67 | + */ | ||
| 68 | + public static function getFromId($data){ | ||
| 69 | + unset($data['globalso-domain_host_url']); | ||
| 70 | + unset($data['globalso-domain']); | ||
| 71 | + unset($data['globalso-edition']); | ||
| 72 | + unset($data['globalso-date']); | ||
| 73 | + ksort($data); | ||
| 74 | + $field = array_keys($data); | ||
| 75 | + $sign = md5(json_encode($field)); | ||
| 76 | + $model = self::where('sign', $sign)->first(); | ||
| 77 | + if(!$model){ | ||
| 78 | + $model = new self(); | ||
| 79 | + $model->sign = $sign; | ||
| 80 | + $model->field = $field; | ||
| 81 | + | ||
| 82 | + if(!empty($data['name']) && !empty($data['email']) && !empty($data['message'])){ | ||
| 83 | + $has_file = false; | ||
| 84 | + foreach ($data as $v){ | ||
| 85 | + if (is_array($v)){ | ||
| 86 | + $has_file = true; | ||
| 87 | + break; | ||
| 88 | + } | ||
| 89 | + } | ||
| 90 | + !$has_file && $model->is_default = 1; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + $model->save(); | ||
| 94 | + } | ||
| 95 | + return $model->id; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + public function setFieldAttribute($value) | ||
| 99 | + { | ||
| 100 | + $this->attributes['field'] = json_encode($value); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + public function getFieldAttribute($value) | ||
| 104 | + { | ||
| 105 | + return json_decode($value, true); | ||
| 106 | + } | ||
| 66 | } | 107 | } |
| @@ -2,6 +2,7 @@ | @@ -2,6 +2,7 @@ | ||
| 2 | 2 | ||
| 3 | namespace App\Models\Inquiry; | 3 | namespace App\Models\Inquiry; |
| 4 | 4 | ||
| 5 | +use App\Helper\FormGlobalsoApi; | ||
| 5 | use App\Models\Base; | 6 | use App\Models\Base; |
| 6 | use Illuminate\Database\Eloquent\SoftDeletes; | 7 | use Illuminate\Database\Eloquent\SoftDeletes; |
| 7 | use Illuminate\Support\Facades\DB; | 8 | use Illuminate\Support\Facades\DB; |
| @@ -23,6 +24,71 @@ class InquiryFormData extends Base | @@ -23,6 +24,71 @@ class InquiryFormData extends Base | ||
| 23 | protected $connection = "custom_mysql"; | 24 | protected $connection = "custom_mysql"; |
| 24 | protected $table = 'gl_inquiry_form_data'; | 25 | protected $table = 'gl_inquiry_form_data'; |
| 25 | 26 | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * 根据提交数据的key获取表单id | ||
| 30 | + * @param $form_id | ||
| 31 | + * @param $domain | ||
| 32 | + * @param $ip | ||
| 33 | + * @param $country | ||
| 34 | + * @param $referer | ||
| 35 | + * @param $user_agent | ||
| 36 | + * @param $submit_at | ||
| 37 | + * @param $data | ||
| 38 | + * @return mixed | ||
| 39 | + * @author zbj | ||
| 40 | + * @date 2023/12/4 | ||
| 41 | + */ | ||
| 42 | + public static function saveData($form_id, $domain, $ip, $country, $referer, $user_agent, $submit_at, $data){ | ||
| 43 | + //数据标识 | ||
| 44 | + ksort($data); | ||
| 45 | + $sign = md5(json_encode($data)); | ||
| 46 | + //5分钟内是否有重复数据 | ||
| 47 | + $is_exist = self::where('sign', $sign)->where('created_at', '>', date('Y-m-d H:i:s', strtotime('-5 minute')))->first(); | ||
| 48 | + if($is_exist){ | ||
| 49 | + return true; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + $model = new self(); | ||
| 53 | + $model->form_id = $form_id; | ||
| 54 | + $model->domain = $domain; | ||
| 55 | + $model->ip = $ip; | ||
| 56 | + $model->country = $country; | ||
| 57 | + $model->referer = $referer; | ||
| 58 | + $model->user_agent = $user_agent; | ||
| 59 | + $model->submit_at = $submit_at; | ||
| 60 | + $model->data = $data; | ||
| 61 | + $model->sign = $sign; | ||
| 62 | + $model->save(); | ||
| 63 | + | ||
| 64 | + if(!empty($data['name']) && !empty($data['email']) && !empty($data['message'])){ | ||
| 65 | + unset($data['globalso-domain_host_url']); | ||
| 66 | + unset($data['globalso-domain']); | ||
| 67 | + unset($data['globalso-edition']); | ||
| 68 | + unset($data['globalso-date']); | ||
| 69 | + | ||
| 70 | + //推送邮件发送 | ||
| 71 | + $has_file = false; | ||
| 72 | + foreach ($data as $k => $v){ | ||
| 73 | + if(is_array($v)){ | ||
| 74 | + $has_file = true; | ||
| 75 | + break; | ||
| 76 | + } | ||
| 77 | + //其他字段补充到message里 | ||
| 78 | + if(!in_array($k, ['name', 'email', 'message', 'phone', 'ip', 'date', 'cname', 'domain', 'edition', 'domain_host_url'])){ | ||
| 79 | + $data['message'].= "<br/>" . $k .': ' . $v; | ||
| 80 | + } | ||
| 81 | + } | ||
| 82 | + !$has_file && (new FormGlobalsoApi())->submitInquiry($ip, $referer, $submit_at, $data); | ||
| 83 | + } | ||
| 84 | + return true; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + public function setDataAttribute($value) | ||
| 88 | + { | ||
| 89 | + $this->attributes['data'] = json_encode($value); | ||
| 90 | + } | ||
| 91 | + | ||
| 26 | public function getDataAttribute($value) | 92 | public function getDataAttribute($value) |
| 27 | { | 93 | { |
| 28 | return json_decode($value, true); | 94 | return json_decode($value, true); |
| @@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
| 3 | namespace App\Models\Project; | 3 | namespace App\Models\Project; |
| 4 | 4 | ||
| 5 | use App\Models\Base; | 5 | use App\Models\Base; |
| 6 | +use Illuminate\Support\Facades\Cache; | ||
| 6 | 7 | ||
| 7 | /** | 8 | /** |
| 8 | * 询盘过滤配置 | 9 | * 询盘过滤配置 |
| @@ -24,4 +25,30 @@ class InquiryFilterConfig extends Base | @@ -24,4 +25,30 @@ class InquiryFilterConfig extends Base | ||
| 24 | 'filter_mobiles' => 'array', | 25 | 'filter_mobiles' => 'array', |
| 25 | 'filter_names' => 'array', | 26 | 'filter_names' => 'array', |
| 26 | ]; | 27 | ]; |
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * @param $project_id | ||
| 31 | + * @return string | ||
| 32 | + * @author zbj | ||
| 33 | + * @date 2024/1/20 | ||
| 34 | + */ | ||
| 35 | + public static function cacheKey($project_id): string | ||
| 36 | + { | ||
| 37 | + return 'project_inquiry_filter_config_info' . $project_id; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + /** | ||
| 41 | + * @param $project_id | ||
| 42 | + * @return mixed | ||
| 43 | + * @author zbj | ||
| 44 | + * @date 2024/1/20 | ||
| 45 | + */ | ||
| 46 | + public static function getCacheInfoByProjectId($project_id){ | ||
| 47 | + $info = Cache::get(self::cacheKey($project_id)); | ||
| 48 | + if (!$info) { | ||
| 49 | + $info = self::where('project_id', $project_id)->first(); | ||
| 50 | + Cache::put(self::cacheKey($project_id), $info, 2 * 3600); | ||
| 51 | + } | ||
| 52 | + return $info; | ||
| 53 | + } | ||
| 27 | } | 54 | } |
app/Models/SyncSubmitTask/SyncSubmitTask.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Models\SyncSubmitTask; | ||
| 4 | + | ||
| 5 | +use Illuminate\Database\Eloquent\Model; | ||
| 6 | +use Illuminate\Support\Facades\Log; | ||
| 7 | +use Illuminate\Support\Facades\Redis; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * @method static where(string $string, mixed $ip) | ||
| 11 | + * @method static create(array $data) | ||
| 12 | + */ | ||
| 13 | +class SyncSubmitTask extends Model | ||
| 14 | +{ | ||
| 15 | + | ||
| 16 | + const TYPE_INQUIRY = 'inquiry'; | ||
| 17 | + const TYPE_VISIT = 'visit'; | ||
| 18 | + | ||
| 19 | + const TRAFFIC_DEFAULT = 0; | ||
| 20 | + const TRAFFIC_TRUE = 1; | ||
| 21 | + | ||
| 22 | + //设置关联表名 | ||
| 23 | + /** | ||
| 24 | + * @var mixed | ||
| 25 | + */ | ||
| 26 | + protected $table = 'gl_sync_submit_task'; | ||
| 27 | + | ||
| 28 | + protected $casts = [ | ||
| 29 | + 'data' => 'array', | ||
| 30 | + ]; | ||
| 31 | +} |
| @@ -4,6 +4,8 @@ namespace App\Models\Visit; | @@ -4,6 +4,8 @@ namespace App\Models\Visit; | ||
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | use App\Models\Base; | 6 | use App\Models\Base; |
| 7 | +use Carbon\Carbon; | ||
| 8 | +use Illuminate\Support\Facades\DB; | ||
| 7 | 9 | ||
| 8 | /** | 10 | /** |
| 9 | * Class Visit | 11 | * Class Visit |
| @@ -19,6 +21,7 @@ class Visit extends Base | @@ -19,6 +21,7 @@ class Visit extends Base | ||
| 19 | //连接数据库 | 21 | //连接数据库 |
| 20 | protected $connection = 'custom_mysql'; | 22 | protected $connection = 'custom_mysql'; |
| 21 | protected $appends = ['device_text']; | 23 | protected $appends = ['device_text']; |
| 24 | + protected $fillable = ['ip','device_port','country','city','url','referrer_url','depth','domain','updated_date', 'created_at']; | ||
| 22 | 25 | ||
| 23 | const DEVICE_PC = 1; | 26 | const DEVICE_PC = 1; |
| 24 | const DEVICE_MOBILE = 2; | 27 | const DEVICE_MOBILE = 2; |
| @@ -47,4 +50,52 @@ class Visit extends Base | @@ -47,4 +50,52 @@ class Visit extends Base | ||
| 47 | return self::deviceMap()[$this->device_port] ?? ''; | 50 | return self::deviceMap()[$this->device_port] ?? ''; |
| 48 | } | 51 | } |
| 49 | 52 | ||
| 53 | + /** | ||
| 54 | + * 访问写入 | ||
| 55 | + */ | ||
| 56 | + public static function saveData($data) | ||
| 57 | + { | ||
| 58 | + //判断IP当天是否有一条数据 | ||
| 59 | + $visit = Visit::where("ip",$data['ip'])->where("created_at",">=",Carbon::now()->today()->startOfDay()) | ||
| 60 | + ->where("created_at","<=",Carbon::now()->today()->endOfDay()) | ||
| 61 | + ->first(); | ||
| 62 | + DB::connection('custom_mysql')->beginTransaction(); | ||
| 63 | + if (!empty($visit) && $visit->count() >= 1){ | ||
| 64 | + //当天已存在IP访问记录 | ||
| 65 | + try{ | ||
| 66 | + $data["customer_visit_id"] = $visit->id; | ||
| 67 | + VisitItem::create($data); | ||
| 68 | + Visit::where("id",$visit->id)->update(['depth' => $visit->depth + 1]); | ||
| 69 | + DB::connection('custom_mysql')->commit(); | ||
| 70 | + }catch (\Exception $e){ | ||
| 71 | + DB::connection('custom_mysql')->rollBack(); | ||
| 72 | + throw new \Exception($e->getMessage()); | ||
| 73 | + } | ||
| 74 | + }else{ | ||
| 75 | + //第一次访问 | ||
| 76 | + try{ | ||
| 77 | + $id = Visit::create($data)->id; | ||
| 78 | + $data["customer_visit_id"] = $id; | ||
| 79 | + VisitItem::create($data); | ||
| 80 | + DB::connection('custom_mysql')->commit(); | ||
| 81 | + }catch (\Exception $e){ | ||
| 82 | + DB::connection('custom_mysql')->rollBack(); | ||
| 83 | + throw new \Exception($e->getMessage()); | ||
| 84 | + } | ||
| 85 | + } | ||
| 86 | + return true; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + | ||
| 90 | + public static function isInquiry($ip){ | ||
| 91 | + $visit = Visit::where("ip",$ip)->where("created_at",">=",Carbon::now()->today()->startOfDay()) | ||
| 92 | + ->where("created_at","<=",Carbon::now()->today()->endOfDay()) | ||
| 93 | + ->first(); | ||
| 94 | + if($visit){ | ||
| 95 | + $visit->is_inquiry = 1; | ||
| 96 | + $visit->save(); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + return true; | ||
| 100 | + } | ||
| 50 | } | 101 | } |
| @@ -16,4 +16,7 @@ class VisitItem extends Base | @@ -16,4 +16,7 @@ class VisitItem extends Base | ||
| 16 | protected $table = 'gl_customer_visit_item'; | 16 | protected $table = 'gl_customer_visit_item'; |
| 17 | //连接数据库 | 17 | //连接数据库 |
| 18 | protected $connection = 'custom_mysql'; | 18 | protected $connection = 'custom_mysql'; |
| 19 | + | ||
| 20 | + protected $fillable = ['ip','customer_visit_id','device_port','country','city','url','referrer_url','domain','updated_date','created_at']; | ||
| 21 | + | ||
| 19 | } | 22 | } |
app/Services/SyncSubmitTaskService.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +namespace App\Services; | ||
| 5 | + | ||
| 6 | +use App\Exceptions\InquiryFilterException; | ||
| 7 | +use App\Models\Inquiry\InquiryForm; | ||
| 8 | +use App\Models\Inquiry\InquiryFormData; | ||
| 9 | +use App\Models\Project\InquiryFilterConfig; | ||
| 10 | +use App\Models\Project\Project; | ||
| 11 | +use App\Models\SyncSubmitTask\SyncSubmitTask; | ||
| 12 | +use App\Models\Visit\Visit; | ||
| 13 | +use Illuminate\Support\Facades\Http; | ||
| 14 | +use Illuminate\Support\Facades\URL; | ||
| 15 | +use Illuminate\Support\Str; | ||
| 16 | +use function Symfony\Component\String\s; | ||
| 17 | + | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * Class SyncSubmitTaskService | ||
| 21 | + * @package App\Services | ||
| 22 | + * @author zbj | ||
| 23 | + * @date 2023/12/4 | ||
| 24 | + */ | ||
| 25 | +class SyncSubmitTaskService | ||
| 26 | +{ | ||
| 27 | + /** | ||
| 28 | + * @param $task | ||
| 29 | + * @return mixed | ||
| 30 | + * @throws InquiryFilterException | ||
| 31 | + * @author zbj | ||
| 32 | + * @date 2023/11/28 | ||
| 33 | + */ | ||
| 34 | + public static function handler($task) | ||
| 35 | + { | ||
| 36 | + $data = $task['data']; | ||
| 37 | + $checkIpCountry = self::checkIpCountry($data['domain'], $data['ip'], $task['type']); | ||
| 38 | + | ||
| 39 | + $data['ip'] = $checkIpCountry['ip']; | ||
| 40 | + $data['country'] = $checkIpCountry['country']; | ||
| 41 | + $data['submit_at'] = $task['created_at']; | ||
| 42 | + $project = $checkIpCountry['project']; | ||
| 43 | + $data['project_id'] = $project['id']; | ||
| 44 | + | ||
| 45 | + //特殊处理 | ||
| 46 | + if($project['id'] == 455 && !empty($data['email']) && $data['email'] == 'alb@marketingtu.org'){ | ||
| 47 | + return false; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + ProjectServer::useProject($project['id']); | ||
| 51 | + | ||
| 52 | + $action = $task['type']; | ||
| 53 | + $handler = new self(); | ||
| 54 | + return $handler->$action($data); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * 询盘 | ||
| 60 | + * @param $data | ||
| 61 | + * @return bool | ||
| 62 | + * @throws InquiryFilterException | ||
| 63 | + * @author zbj | ||
| 64 | + * @date 2023/12/4 | ||
| 65 | + */ | ||
| 66 | + public function inquiry($data) | ||
| 67 | + { | ||
| 68 | + | ||
| 69 | + $this->inquiryFilter($data['project_id'], $data); | ||
| 70 | + | ||
| 71 | + $form_id = InquiryForm::getFromId($data['data']); | ||
| 72 | + | ||
| 73 | + InquiryFormData::saveData($form_id, $data['domain'], $data['ip'], $data['country'], $data['referer'], $data['user_agent'], $data['submit_at'], $data['data']); | ||
| 74 | + | ||
| 75 | + //转化询盘 | ||
| 76 | + Visit::isInquiry($data['ip']); | ||
| 77 | + | ||
| 78 | + return true; | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + /** | ||
| 82 | + * 访问 | ||
| 83 | + * @param $data | ||
| 84 | + * @return bool | ||
| 85 | + * @throws \Exception | ||
| 86 | + * @author zbj | ||
| 87 | + * @date 2023/12/4 | ||
| 88 | + */ | ||
| 89 | + public function visit($data) | ||
| 90 | + { | ||
| 91 | + | ||
| 92 | + $visit_data = $data['data']; | ||
| 93 | + $visit_data['referrer_url'] = $data['data']['referrer_url']??''; | ||
| 94 | + $visit_data['device_port'] = $data['data']['device_port']??''; | ||
| 95 | + $visit_data['url'] = $data['data']['url']??''; | ||
| 96 | + $visit_data['domain'] = $data['domain']??''; | ||
| 97 | + $visit_data['ip'] = $data['ip']; | ||
| 98 | + $visit_data['country'] = $data['country']; | ||
| 99 | + $visit_data['updated_date'] = $data['submit_at']->toDateString(); | ||
| 100 | + $visit_data['created_at'] = $data['submit_at']; | ||
| 101 | + Visit::saveData($visit_data); | ||
| 102 | + | ||
| 103 | + return true; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + /** | ||
| 107 | + * 根据ip查地区 | ||
| 108 | + * @param $ip | ||
| 109 | + * @return string | ||
| 110 | + * @author zbj | ||
| 111 | + * @date 2023/11/28 | ||
| 112 | + */ | ||
| 113 | + public static function getCountryByIp($ip){ | ||
| 114 | + if(!$ip){ | ||
| 115 | + return ''; | ||
| 116 | + } | ||
| 117 | + $res = Http::withoutVerifying()->get('http://ip.globalso.com', ['ip' => $ip]); | ||
| 118 | + if($res->status() == 200){ | ||
| 119 | + return $res->body(); | ||
| 120 | + }else{ | ||
| 121 | + return ''; | ||
| 122 | + } | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + /** | ||
| 126 | + * 是否开始测试站或中国内地询盘和访问记录 | ||
| 127 | + * @param $domain | ||
| 128 | + * @param $ip | ||
| 129 | + * @param $type | ||
| 130 | + * @return array | ||
| 131 | + * @throws InquiryFilterException | ||
| 132 | + * @author zbj | ||
| 133 | + * @date 2023/11/30 | ||
| 134 | + */ | ||
| 135 | + public static function checkIpCountry($domain, $ip, $type){ | ||
| 136 | + $domain = 'https://demo.globalso.site/'; | ||
| 137 | + $project = Project::getProjectByDomain($domain); | ||
| 138 | + if(empty($project)){ | ||
| 139 | + throw new InquiryFilterException('项目不存在'); | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + // 测试环境返回信息 | ||
| 143 | + if (FALSE !== strpos($domain, 'globalso.site') && !$project->is_record_test_visit) { | ||
| 144 | + throw new InquiryFilterException('测试环境过滤'); | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + if($ip == "127.0.0.1"){ | ||
| 148 | + throw new InquiryFilterException('127.0.0.1过滤'); | ||
| 149 | + } | ||
| 150 | + $country = self::getCountryByIp($ip); | ||
| 151 | + //访问记录才过滤是否国内 | ||
| 152 | + if ($country == "中国" && !$project->is_record_china_visit && $type == SyncSubmitTask::TYPE_VISIT){ | ||
| 153 | + throw new InquiryFilterException('中国内地过滤'); | ||
| 154 | + } | ||
| 155 | + return [ | ||
| 156 | + 'project' => $project, | ||
| 157 | + 'ip' => $ip, | ||
| 158 | + 'country' => $country | ||
| 159 | + ]; | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + | ||
| 163 | + /** | ||
| 164 | + * 询盘配置过滤 | ||
| 165 | + * @author zbj | ||
| 166 | + * @date 2024/1/20 | ||
| 167 | + */ | ||
| 168 | + public static function inquiryFilter($project_id, $data){ | ||
| 169 | + $config = InquiryFilterConfig::getCacheInfoByProjectId($project_id); | ||
| 170 | + //是否开启过滤 | ||
| 171 | + if($config && $config['status']){ | ||
| 172 | + //是否包含全局规则(就是project_id=1的配置) | ||
| 173 | + if($project_id != Project::DEMO_PROJECT_ID && $config['is_global_rule']){ | ||
| 174 | + self::inquiryFilter(Project::DEMO_PROJECT_ID, $data); | ||
| 175 | + } | ||
| 176 | + //过滤国家 | ||
| 177 | + if($config['filter_countries'] && in_array($data['country'], $config['filter_countries'])){ | ||
| 178 | + throw new InquiryFilterException( '过滤国家:' . $data['country']); | ||
| 179 | + } | ||
| 180 | + //过滤ip | ||
| 181 | + if($config['black_ips']){ | ||
| 182 | + $black_ips = explode("\r\n", $config['black_ips']); | ||
| 183 | + //后端获取的ip | ||
| 184 | + if(in_array($data['ip'], $black_ips)){ | ||
| 185 | + throw new InquiryFilterException( '过滤黑名单IP:' . $data['ip']); | ||
| 186 | + } | ||
| 187 | + //前端获取的ip | ||
| 188 | + if(!empty($data['data']['ip']) && in_array($data['data']['ip'], $black_ips)){ | ||
| 189 | + throw new InquiryFilterException( '过滤黑名单IP:' . $data['data']['ip']); | ||
| 190 | + } | ||
| 191 | + } | ||
| 192 | + //过滤内容 | ||
| 193 | + if(!empty($data['data']['message'])) { | ||
| 194 | + //过滤内容关键字 | ||
| 195 | + if ($config['filter_contents']){ | ||
| 196 | + foreach ($config['filter_contents'] as $filter_content) { | ||
| 197 | + if (Str::contains($data['data']['message'], $filter_content)) { | ||
| 198 | + throw new InquiryFilterException('过滤内容:' . $filter_content); | ||
| 199 | + } | ||
| 200 | + } | ||
| 201 | + } | ||
| 202 | + //是否允许包含链接 | ||
| 203 | + if(!$config['is_allow_link']){ | ||
| 204 | + if (Str::contains($data['data']['message'], ['http://', 'https://', 'www.'])) { | ||
| 205 | + throw new InquiryFilterException('不允许包含链接'); | ||
| 206 | + } | ||
| 207 | + } | ||
| 208 | + } | ||
| 209 | + //过滤来源 | ||
| 210 | + if($config['filter_referers']){ | ||
| 211 | + //只比较path路径 | ||
| 212 | + $paths = array_map(function ($v){ | ||
| 213 | + return parse_url(Url::to($v), PHP_URL_PATH); | ||
| 214 | + },$config['filter_referers']); | ||
| 215 | + | ||
| 216 | + //后端获取的referer | ||
| 217 | + if(in_array(parse_url($data['referer'], PHP_URL_PATH), $paths)){ | ||
| 218 | + throw new InquiryFilterException( '过滤来源链接:' . $data['referer']); | ||
| 219 | + } | ||
| 220 | + //前端获取的referer | ||
| 221 | + if(!empty($data['data']['globalso-domain_host_url']) && in_array(parse_url($data['data']['globalso-domain_host_url'], PHP_URL_PATH), $paths)){ | ||
| 222 | + throw new InquiryFilterException( '过滤来源链接:' . $data['data']['globalso-domain_host_url']); | ||
| 223 | + } | ||
| 224 | + } | ||
| 225 | + //过滤邮箱 | ||
| 226 | + if($config['filter_emails'] && !empty($data['data']['email'])){ | ||
| 227 | + foreach ($config['filter_emails'] as $filter_email){ | ||
| 228 | + if($data['data']['email'] == $filter_email){ | ||
| 229 | + throw new InquiryFilterException( '过滤邮箱:' . $filter_email); | ||
| 230 | + } | ||
| 231 | + } | ||
| 232 | + } | ||
| 233 | + //过滤电话 | ||
| 234 | + if($config['filter_mobiles'] && !empty($data['data']['phone'])){ | ||
| 235 | + foreach ($config['filter_mobiles'] as $filter_mobile){ | ||
| 236 | + if($data['data']['phone'] == $filter_mobile){ | ||
| 237 | + throw new InquiryFilterException( '过滤电话:' . $filter_mobile); | ||
| 238 | + } | ||
| 239 | + } | ||
| 240 | + } | ||
| 241 | + //过滤姓名 | ||
| 242 | + if($config['filter_names'] && !empty($data['data']['name'])){ | ||
| 243 | + foreach ($config['filter_names'] as $filter_name){ | ||
| 244 | + if($data['data']['name'] == $filter_name){ | ||
| 245 | + throw new InquiryFilterException( '过滤姓名:' . $filter_name); | ||
| 246 | + } | ||
| 247 | + } | ||
| 248 | + } | ||
| 249 | + } | ||
| 250 | + return true; | ||
| 251 | + } | ||
| 252 | + | ||
| 253 | +} |
-
请 注册 或 登录 后发表评论