|
|
|
1
|
+<?php
|
|
|
|
2
|
+/**
|
|
|
|
3
|
+ * Created by PhpStorm.
|
|
|
|
4
|
+ * User: zhl
|
|
|
|
5
|
+ * Date: 2024/09/30
|
|
|
|
6
|
+ * Time: 11:51
|
|
|
|
7
|
+ */
|
|
|
|
8
|
+namespace App\Console\Commands\Inquiry;
|
|
|
|
9
|
+
|
|
|
|
10
|
+use App\Helper\Common;
|
|
|
|
11
|
+use App\Helper\Gpt;
|
|
|
|
12
|
+use App\Helper\Translate;
|
|
|
|
13
|
+use App\Helper\Validate;
|
|
|
|
14
|
+use App\Models\Ai\AiCommand;
|
|
|
|
15
|
+use App\Models\Inquiry\ReInquiryConfig;
|
|
|
|
16
|
+use App\Models\Inquiry\ReInquiryDetail;
|
|
|
|
17
|
+use App\Models\Inquiry\ReInquiryDetailLog;
|
|
|
|
18
|
+use App\Models\Inquiry\ReInquiryForm;
|
|
|
|
19
|
+use App\Models\Inquiry\ReInquiryTask;
|
|
|
|
20
|
+use App\Models\Inquiry\ReInquiryText;
|
|
|
|
21
|
+use App\Models\Project\InquiryFilterConfig;
|
|
|
|
22
|
+use App\Models\Project\Project;
|
|
|
|
23
|
+use App\Models\WebSetting\WebLanguage;
|
|
|
|
24
|
+use Illuminate\Console\Command;
|
|
|
|
25
|
+use Illuminate\Support\Arr;
|
|
|
|
26
|
+use Illuminate\Support\Facades\Cache;
|
|
|
|
27
|
+use Illuminate\Support\Facades\DB;
|
|
|
|
28
|
+use Illuminate\Support\Facades\Http;
|
|
|
|
29
|
+use Illuminate\Support\Facades\Log;
|
|
|
|
30
|
+use Illuminate\Support\Str;
|
|
|
|
31
|
+
|
|
|
|
32
|
+/**
|
|
|
|
33
|
+ * Class RelayInquiry
|
|
|
|
34
|
+ * @package App\Console\Commands\Inquiry
|
|
|
|
35
|
+ */
|
|
|
|
36
|
+class RelayInquiryTest extends Command
|
|
|
|
37
|
+{
|
|
|
|
38
|
+ /**
|
|
|
|
39
|
+ * The name and signature of the console command.
|
|
|
|
40
|
+ *
|
|
|
|
41
|
+ * @var string
|
|
|
|
42
|
+ */
|
|
|
|
43
|
+ protected $signature = 'relay_inquiry_test';
|
|
|
|
44
|
+
|
|
|
|
45
|
+ /**
|
|
|
|
46
|
+ * The console command description.
|
|
|
|
47
|
+ *
|
|
|
|
48
|
+ * @var string
|
|
|
|
49
|
+ */
|
|
|
|
50
|
+ protected $description = '重启失败的转发询盘';
|
|
|
|
51
|
+
|
|
|
|
52
|
+ /**
|
|
|
|
53
|
+ * Create a new command instance.
|
|
|
|
54
|
+ *
|
|
|
|
55
|
+ * @return void
|
|
|
|
56
|
+ */
|
|
|
|
57
|
+ public function __construct()
|
|
|
|
58
|
+ {
|
|
|
|
59
|
+ parent::__construct();
|
|
|
|
60
|
+ }
|
|
|
|
61
|
+
|
|
|
|
62
|
+ /**
|
|
|
|
63
|
+ * 模拟访问来源占比
|
|
|
|
64
|
+ * @var array
|
|
|
|
65
|
+ */
|
|
|
|
66
|
+ protected $lyzb = [
|
|
|
|
67
|
+ 'https://www.google.com/' => 630,
|
|
|
|
68
|
+ 'http://www.google.com/' => 30,
|
|
|
|
69
|
+ 'http://www.bing.com/' => 20,
|
|
|
|
70
|
+ 'https://www.bing.com/' => 5,
|
|
|
|
71
|
+ 'https://www.youtube.com/' => 5,
|
|
|
|
72
|
+ 'https://search.yahoo.com/' => 5,
|
|
|
|
73
|
+ 'https://www.facebook.com/' => 5,
|
|
|
|
74
|
+ ];
|
|
|
|
75
|
+
|
|
|
|
76
|
+ /**
|
|
|
|
77
|
+ * 俄语站 模拟访问来源占比
|
|
|
|
78
|
+ * @var array
|
|
|
|
79
|
+ */
|
|
|
|
80
|
+ protected $eylyzb = [
|
|
|
|
81
|
+ 'https://www.yandex.com/' => 630,
|
|
|
|
82
|
+ 'https://www.google.com/' => 30,
|
|
|
|
83
|
+ 'http://www.google.com/' => 30,
|
|
|
|
84
|
+ 'http://www.bing.com/' => 20,
|
|
|
|
85
|
+ 'https://www.bing.com/' => 5,
|
|
|
|
86
|
+ 'https://www.youtube.com/' => 5,
|
|
|
|
87
|
+ 'https://search.yahoo.com/' => 5,
|
|
|
|
88
|
+ 'https://www.facebook.com/' => 5,
|
|
|
|
89
|
+ ];
|
|
|
|
90
|
+
|
|
|
|
91
|
+ /**
|
|
|
|
92
|
+ * PC端访问头信息
|
|
|
|
93
|
+ * @var array
|
|
|
|
94
|
+ */
|
|
|
|
95
|
+ protected $pc_ua = [
|
|
|
|
96
|
+ 0 => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
|
|
|
|
97
|
+ 1 => 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
|
|
|
|
98
|
+ 2 => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1'
|
|
|
|
99
|
+ ];
|
|
|
|
100
|
+
|
|
|
|
101
|
+ /**
|
|
|
|
102
|
+ * 移动端访问头信息
|
|
|
|
103
|
+ * @var array
|
|
|
|
104
|
+ */
|
|
|
|
105
|
+ protected $mobile_ua = [
|
|
|
|
106
|
+ 0 => 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko; googleweblight) Chrome/38.0.1025.166 Mobile Safari/535.19',
|
|
|
|
107
|
+ ];
|
|
|
|
108
|
+
|
|
|
|
109
|
+ /**
|
|
|
|
110
|
+ * google域名后缀
|
|
|
|
111
|
+ * @var string[]
|
|
|
|
112
|
+ */
|
|
|
|
113
|
+ protected $suffix = [
|
|
|
|
114
|
+ 'co.jp' => '日本',
|
|
|
|
115
|
+ 'com.tr' => '土耳其',
|
|
|
|
116
|
+ 'nl' => '荷兰',
|
|
|
|
117
|
+ 'ru' => '俄罗斯',
|
|
|
|
118
|
+ 'fr' => '法国',
|
|
|
|
119
|
+ 'co.kr' => '韩国',
|
|
|
|
120
|
+ 'fi' => '芬兰',
|
|
|
|
121
|
+ 'be' => '比利时',
|
|
|
|
122
|
+ 'lt' => '立陶宛',
|
|
|
|
123
|
+ 'es' => '西班牙',
|
|
|
|
124
|
+ 'it' => '意大利',
|
|
|
|
125
|
+ 'com.au' => '澳大利亚',
|
|
|
|
126
|
+ 'no' => '挪威',
|
|
|
|
127
|
+ 'al' => '阿尔巴尼亚',
|
|
|
|
128
|
+ 'pt' => '葡萄牙',
|
|
|
|
129
|
+ 'lv' => '拉脱维亚',
|
|
|
|
130
|
+ 'hu' => '匈牙利',
|
|
|
|
131
|
+ 'cz' => '捷克',
|
|
|
|
132
|
+ 'de' => '德国',
|
|
|
|
133
|
+ 'ca' => '加拿大',
|
|
|
|
134
|
+ 'co.in' => '印度',
|
|
|
|
135
|
+ 'co.uk' => '英国',
|
|
|
|
136
|
+ 'com.vn' => '越南',
|
|
|
|
137
|
+ 'com.br' => '巴西',
|
|
|
|
138
|
+ 'co.il' => '以色列',
|
|
|
|
139
|
+ 'pl' => '波兰',
|
|
|
|
140
|
+ 'com.eg' => '埃及',
|
|
|
|
141
|
+ 'co.th' => '泰国',
|
|
|
|
142
|
+ 'sk' => '斯洛伐克',
|
|
|
|
143
|
+ 'ro' => '罗马尼亚',
|
|
|
|
144
|
+ 'com.mx' => '墨西哥',
|
|
|
|
145
|
+ 'com.my' => '马来西亚',
|
|
|
|
146
|
+ 'com.pk' => '巴基斯坦',
|
|
|
|
147
|
+ 'co.nz' => '新西兰',
|
|
|
|
148
|
+ 'co.za' => '南非',
|
|
|
|
149
|
+ 'com.ar' => '阿根廷',
|
|
|
|
150
|
+ 'com.kw' => '科威特',
|
|
|
|
151
|
+ 'com.sg' => '新加坡',
|
|
|
|
152
|
+ 'com.co' => '哥伦比亚',
|
|
|
|
153
|
+ 'co.id' => '印度尼西亚',
|
|
|
|
154
|
+ 'gr' => '希腊',
|
|
|
|
155
|
+ 'bg' => '保加利亚',
|
|
|
|
156
|
+ 'mn' => '蒙古',
|
|
|
|
157
|
+ 'dk' => '丹麦',
|
|
|
|
158
|
+ 'com.sa' => '沙特阿拉伯',
|
|
|
|
159
|
+ 'com.pe' => '秘鲁',
|
|
|
|
160
|
+ 'com.ph' => '菲律宾',
|
|
|
|
161
|
+ 'com.ua' => '乌克兰',
|
|
|
|
162
|
+ 'ge' => '格鲁吉亚',
|
|
|
|
163
|
+ 'ae' => '阿拉伯联合酋长国',
|
|
|
|
164
|
+ 'tn' => '突尼斯',
|
|
|
|
165
|
+ ];
|
|
|
|
166
|
+
|
|
|
|
167
|
+ protected $otherzb = [700, 300]; //模拟访问来源占比 (非美国) google.com|google.其他后缀
|
|
|
|
168
|
+
|
|
|
|
169
|
+ /**
|
|
|
|
170
|
+ * 手机号过滤 0去掉+ 1不转发手机 2不处理
|
|
|
|
171
|
+ * @var int[]
|
|
|
|
172
|
+ */
|
|
|
|
173
|
+ protected $filter_phone = [30,12,58];
|
|
|
|
174
|
+
|
|
|
|
175
|
+ /**
|
|
|
|
176
|
+ * 需要多个ip访问的国家
|
|
|
|
177
|
+ * @var
|
|
|
|
178
|
+ */
|
|
|
|
179
|
+ protected $multiple_ip_visit_country = [
|
|
|
|
180
|
+ '阿尔及利亚',
|
|
|
|
181
|
+ '埃及',
|
|
|
|
182
|
+ '埃塞俄比亚',
|
|
|
|
183
|
+ '安哥拉',
|
|
|
|
184
|
+ '贝宁',
|
|
|
|
185
|
+ '博茨瓦纳',
|
|
|
|
186
|
+ '布基纳法索',
|
|
|
|
187
|
+ '布隆迪',
|
|
|
|
188
|
+ '赤道几内亚',
|
|
|
|
189
|
+ '多哥',
|
|
|
|
190
|
+ '厄立特里亚',
|
|
|
|
191
|
+ '佛得角',
|
|
|
|
192
|
+ '冈比亚',
|
|
|
|
193
|
+ '刚果共和国',
|
|
|
|
194
|
+ '刚果民主共和国',
|
|
|
|
195
|
+ '吉布提',
|
|
|
|
196
|
+ '几内亚',
|
|
|
|
197
|
+ '几内亚比绍共和国',
|
|
|
|
198
|
+ '加纳',
|
|
|
|
199
|
+ '加蓬',
|
|
|
|
200
|
+ '津巴布韦',
|
|
|
|
201
|
+ '喀麦隆',
|
|
|
|
202
|
+ '科摩罗',
|
|
|
|
203
|
+ '科特迪瓦',
|
|
|
|
204
|
+ '肯尼亚',
|
|
|
|
205
|
+ '莱索托',
|
|
|
|
206
|
+ '利比里亚',
|
|
|
|
207
|
+ '利比亞',
|
|
|
|
208
|
+ '留尼汪',
|
|
|
|
209
|
+ '卢旺达',
|
|
|
|
210
|
+ '马达加斯加',
|
|
|
|
211
|
+ '马拉维',
|
|
|
|
212
|
+ '马里',
|
|
|
|
213
|
+ '马约特',
|
|
|
|
214
|
+ '毛里求斯',
|
|
|
|
215
|
+ '毛里塔尼亚',
|
|
|
|
216
|
+ '摩洛哥',
|
|
|
|
217
|
+ '莫桑比克',
|
|
|
|
218
|
+ '纳米比亚',
|
|
|
|
219
|
+ '南非',
|
|
|
|
220
|
+ '南苏丹',
|
|
|
|
221
|
+ '尼日尔',
|
|
|
|
222
|
+ '尼日利亚',
|
|
|
|
223
|
+ '塞拉利昂',
|
|
|
|
224
|
+ '塞内加尔',
|
|
|
|
225
|
+ '塞舌尔',
|
|
|
|
226
|
+ '圣多美和普林西比',
|
|
|
|
227
|
+ '圣赫勒拿',
|
|
|
|
228
|
+ '斯威士兰',
|
|
|
|
229
|
+ '索马里',
|
|
|
|
230
|
+ '坦桑尼亚',
|
|
|
|
231
|
+ '突尼斯',
|
|
|
|
232
|
+ '乌干达',
|
|
|
|
233
|
+ '西撒哈拉',
|
|
|
|
234
|
+ '赞比亚',
|
|
|
|
235
|
+ '乍得',
|
|
|
|
236
|
+ '中非共和国',
|
|
|
|
237
|
+ '阿富汗',
|
|
|
|
238
|
+ '阿联酋',
|
|
|
|
239
|
+ '阿曼',
|
|
|
|
240
|
+ '阿塞拜疆',
|
|
|
|
241
|
+ '澳门',
|
|
|
|
242
|
+ '巴基斯坦',
|
|
|
|
243
|
+ '巴勒斯坦',
|
|
|
|
244
|
+ '巴林',
|
|
|
|
245
|
+ '不丹',
|
|
|
|
246
|
+ '东帝汶',
|
|
|
|
247
|
+ '菲律宾',
|
|
|
|
248
|
+ '格鲁吉亚',
|
|
|
|
249
|
+ '哈萨克斯坦',
|
|
|
|
250
|
+ '韩国',
|
|
|
|
251
|
+ '吉尔吉斯斯坦',
|
|
|
|
252
|
+ '柬埔寨',
|
|
|
|
253
|
+ '卡塔尔',
|
|
|
|
254
|
+ '科威特',
|
|
|
|
255
|
+ '老挝',
|
|
|
|
256
|
+ '黎巴嫩',
|
|
|
|
257
|
+ '马尔代夫',
|
|
|
|
258
|
+ '马来西亚',
|
|
|
|
259
|
+ '蒙古',
|
|
|
|
260
|
+ '孟加拉国',
|
|
|
|
261
|
+ '缅甸',
|
|
|
|
262
|
+ '尼泊尔',
|
|
|
|
263
|
+ '日本',
|
|
|
|
264
|
+ '塞浦路斯',
|
|
|
|
265
|
+ '沙特阿拉伯',
|
|
|
|
266
|
+ '斯里兰卡',
|
|
|
|
267
|
+ '塔吉克斯坦',
|
|
|
|
268
|
+ '泰国',
|
|
|
|
269
|
+ '土耳其',
|
|
|
|
270
|
+ '土库曼斯坦',
|
|
|
|
271
|
+ '文莱',
|
|
|
|
272
|
+ '乌兹别克斯坦',
|
|
|
|
273
|
+ '新加坡',
|
|
|
|
274
|
+ '亚美尼亚',
|
|
|
|
275
|
+ '也门',
|
|
|
|
276
|
+ '伊拉克',
|
|
|
|
277
|
+ '以色列',
|
|
|
|
278
|
+ '印度尼西亚',
|
|
|
|
279
|
+ '约旦',
|
|
|
|
280
|
+ '越南',
|
|
|
|
281
|
+ ];
|
|
|
|
282
|
+
|
|
|
|
283
|
+ /**
|
|
|
|
284
|
+ * @return bool
|
|
|
|
285
|
+ */
|
|
|
|
286
|
+ public function handle()
|
|
|
|
287
|
+ {
|
|
|
|
288
|
+ while (true) {
|
|
|
|
289
|
+ $inquiry = ReInquiryForm::where('created_at', '>', '2025-05-19 00:00:00')
|
|
|
|
290
|
+ ->where('created_at', '<', '2025-05-22 18:00:00')
|
|
|
|
291
|
+ ->where(['status' => ReInquiryForm::STATUS_FORGO])
|
|
|
|
292
|
+ ->where('remark', '超时72小时未处理!')
|
|
|
|
293
|
+ ->orderBy('id', 'asc')->get();
|
|
|
|
294
|
+
|
|
|
|
295
|
+ if ($inquiry->isEmpty()){
|
|
|
|
296
|
+ $this->output('未发现待处理询盘!');
|
|
|
|
297
|
+ sleep(60);
|
|
|
|
298
|
+ continue;
|
|
|
|
299
|
+ }
|
|
|
|
300
|
+
|
|
|
|
301
|
+ $this->output('开始处理本轮询盘!');
|
|
|
|
302
|
+ foreach ($inquiry as $key=>$val) {
|
|
|
|
303
|
+ $this->output('询盘ID:' . $val->id);
|
|
|
|
304
|
+
|
|
|
|
305
|
+
|
|
|
|
306
|
+ $detail_ids = ReInquiryDetail::where('form_id', $val->id)->pluck('id')->toArray();
|
|
|
|
307
|
+
|
|
|
|
308
|
+ $inquiry_log = ReInquiryDetailLog::whereIn('detail_id', $detail_ids)->where('type', ReInquiryDetailLog::TYPE_INQUIRY)->first();
|
|
|
|
309
|
+ //有询盘的了 就跳过
|
|
|
|
310
|
+ if($inquiry_log){
|
|
|
|
311
|
+ continue;
|
|
|
|
312
|
+ }
|
|
|
|
313
|
+
|
|
|
|
314
|
+ // 询盘对应广告
|
|
|
|
315
|
+ $ad_task = $this->getAdTask($val->ad_id);
|
|
|
|
316
|
+ // 没有获取到转发任务
|
|
|
|
317
|
+ if (empty($ad_task)) {
|
|
|
|
318
|
+ $val->status = ReInquiryForm::STATUS_FORGO;
|
|
|
|
319
|
+ $val->remark = '未找到需要转发的广告任务!';
|
|
|
|
320
|
+ $val->save();
|
|
|
|
321
|
+ continue;
|
|
|
|
322
|
+ }
|
|
|
|
323
|
+ // 未设置对法对象
|
|
|
|
324
|
+ $target_num_arr = array_map(function ($item) {
|
|
|
|
325
|
+ return count($item['target']) + count($item['shop_site']) + count($item['fob_pro']);
|
|
|
|
326
|
+ }, $ad_task);
|
|
|
|
327
|
+ if (!array_sum($target_num_arr)) {
|
|
|
|
328
|
+ $val->status = ReInquiryForm::STATUS_FORGO;
|
|
|
|
329
|
+ $val->remark = '广告任务转发对象为空!';
|
|
|
|
330
|
+ $val->save();
|
|
|
|
331
|
+ continue;
|
|
|
|
332
|
+ }
|
|
|
|
333
|
+ //是否要过滤
|
|
|
|
334
|
+ $filter_res = $this->filter($val);
|
|
|
|
335
|
+ if($filter_res !== true){
|
|
|
|
336
|
+ $val->status = ReInquiryForm::STATUS_FORGO;
|
|
|
|
337
|
+ $val->remark = $filter_res;
|
|
|
|
338
|
+ $val->save();
|
|
|
|
339
|
+ continue;
|
|
|
|
340
|
+ }
|
|
|
|
341
|
+ //验证手机号 无效 号码不推送
|
|
|
|
342
|
+ if(!Validate::phone($val->phone)){
|
|
|
|
343
|
+ $val->phone = '';
|
|
|
|
344
|
+ }
|
|
|
|
345
|
+ try {
|
|
|
|
346
|
+ $res = false;
|
|
|
|
347
|
+ foreach ($ad_task as $task){
|
|
|
|
348
|
+ $res += $this->relayDetail($task, $val);
|
|
|
|
349
|
+ $res += $this->relayShopDetail($task, $val);
|
|
|
|
350
|
+ $res += $this->relayFobDetail($task, $val);
|
|
|
|
351
|
+ }
|
|
|
|
352
|
+ $val->status = $res ? ReInquiryForm::STATUS_SUCCESS : ReInquiryForm::STATUS_FORGO;
|
|
|
|
353
|
+ $val->save();
|
|
|
|
354
|
+ } catch (\Exception $e) {
|
|
|
|
355
|
+ $this->logChannel()->info('执行询盘错误:',[$e->getMessage(), $e->getFile(), $e->getLine()]);
|
|
|
|
356
|
+ $this->output('执行询盘错误:' . $e->getMessage());
|
|
|
|
357
|
+ }
|
|
|
|
358
|
+ }
|
|
|
|
359
|
+ $this->output('本轮询盘处理结束!');
|
|
|
|
360
|
+ }
|
|
|
|
361
|
+ return true;
|
|
|
|
362
|
+ }
|
|
|
|
363
|
+
|
|
|
|
364
|
+
|
|
|
|
365
|
+ public function filter($data)
|
|
|
|
366
|
+ {
|
|
|
|
367
|
+ //通用过滤规则
|
|
|
|
368
|
+ $config = InquiryFilterConfig::getCacheInfoByProjectId(Project::DEMO_PROJECT_ID);
|
|
|
|
369
|
+ //FB询盘的全局过滤规则
|
|
|
|
370
|
+ $fb_config = ReInquiryConfig::getDefaultConfigCache(ReInquiryConfig::TYPE_FILTER_WORDS);
|
|
|
|
371
|
+
|
|
|
|
372
|
+ $fb_config['filter_contents'] = array_filter(explode("\r\n", $fb_config['filter_contents']??''));
|
|
|
|
373
|
+ $fb_config['filter_emails'] = array_filter(explode("\r\n", $fb_config['filter_emails']??''));
|
|
|
|
374
|
+ $fb_config['filter_mobiles'] = array_filter(explode("\r\n", $fb_config['filter_mobiles']??''));
|
|
|
|
375
|
+ $fb_config['filter_names'] = array_filter(explode("\r\n", $fb_config['filter_names']??''));
|
|
|
|
376
|
+
|
|
|
|
377
|
+ $config['filter_contents'] = array_unique(array_merge($fb_config['filter_contents'],$config['filter_contents']));
|
|
|
|
378
|
+ $config['filter_emails'] = array_unique(array_merge($fb_config['filter_emails'],$config['filter_emails']));
|
|
|
|
379
|
+ $config['filter_mobiles'] = array_unique(array_merge($fb_config['filter_mobiles'],$config['filter_mobiles']));
|
|
|
|
380
|
+ $config['filter_names'] = array_unique(array_merge($fb_config['filter_names'],$config['filter_names']));
|
|
|
|
381
|
+
|
|
|
|
382
|
+ //过滤内容
|
|
|
|
383
|
+ if(!empty($data['message']) && !empty($config['filter_contents'])) {
|
|
|
|
384
|
+ foreach ($config['filter_contents'] as $filter_content) {
|
|
|
|
385
|
+ if (Str::contains(strtolower($data['message']), strtolower($filter_content))) {
|
|
|
|
386
|
+ return '过滤内容:' . $filter_content;
|
|
|
|
387
|
+ }
|
|
|
|
388
|
+ }
|
|
|
|
389
|
+ }
|
|
|
|
390
|
+ //过滤邮箱
|
|
|
|
391
|
+ if(!empty($data['email']) && !empty($config['filter_emails'])){
|
|
|
|
392
|
+ foreach ($config['filter_emails'] as $filter_email){
|
|
|
|
393
|
+ if(Str::contains(strtolower($data['email']), strtolower($filter_email))){
|
|
|
|
394
|
+ return '过滤邮箱:' . $filter_email;
|
|
|
|
395
|
+ }
|
|
|
|
396
|
+ }
|
|
|
|
397
|
+ //邮箱有效性
|
|
|
|
398
|
+ if(!Validate::email($data['email'])){
|
|
|
|
399
|
+ return '邮箱无效';
|
|
|
|
400
|
+ }
|
|
|
|
401
|
+ }
|
|
|
|
402
|
+ //过滤电话
|
|
|
|
403
|
+ if(!empty($data['phone']) && !empty($config['filter_mobiles'])){
|
|
|
|
404
|
+ foreach ($config['filter_mobiles'] as $filter_mobile){
|
|
|
|
405
|
+ if(Str::contains(strtolower($data['phone']), strtolower($filter_mobile))){
|
|
|
|
406
|
+ return '过滤电话:' . $filter_mobile;
|
|
|
|
407
|
+ }
|
|
|
|
408
|
+ }
|
|
|
|
409
|
+ }
|
|
|
|
410
|
+ //过滤姓名
|
|
|
|
411
|
+ if(!empty($data['full_name'] && !empty($config['filter_names']))){
|
|
|
|
412
|
+ foreach ($config['filter_names'] as $filter_name){
|
|
|
|
413
|
+ if(Str::contains(strtolower($data['full_name']), strtolower($filter_name))){
|
|
|
|
414
|
+ return '过滤姓名:' . $filter_name;
|
|
|
|
415
|
+ }
|
|
|
|
416
|
+ }
|
|
|
|
417
|
+ }
|
|
|
|
418
|
+ return true;
|
|
|
|
419
|
+ }
|
|
|
|
420
|
+
|
|
|
|
421
|
+ /**
|
|
|
|
422
|
+ * 创建转发详情
|
|
|
|
423
|
+ * TODO 通过任务生成转发对象, 更具转发对象获取对应数据, 写入着陆记录
|
|
|
|
424
|
+ * @param $task
|
|
|
|
425
|
+ * @param $form
|
|
|
|
426
|
+ * @return bool
|
|
|
|
427
|
+ */
|
|
|
|
428
|
+ public function relayDetail($task, $form)
|
|
|
|
429
|
+ {
|
|
|
|
430
|
+ $this->output('获取转发对象');
|
|
|
|
431
|
+ if(empty($task['target'] )){
|
|
|
|
432
|
+ $this->output('没有独立站转发对象');
|
|
|
|
433
|
+ return 0;
|
|
|
|
434
|
+ }
|
|
|
|
435
|
+ //是否有必选的渠道 渠道有一个及以上必选 就在组内随机一个
|
|
|
|
436
|
+ $require_agent_group = [];
|
|
|
|
437
|
+ foreach ($task['target'] as $item) {
|
|
|
|
438
|
+ if (!empty($item['is_require'])) {
|
|
|
|
439
|
+ $require_agent_group[] = $item['agent_group'];
|
|
|
|
440
|
+ }
|
|
|
|
441
|
+ }
|
|
|
|
442
|
+ $require_agent_group = array_unique($require_agent_group);
|
|
|
|
443
|
+ $require_agent_group_data = collect($task['target'])->whereIn('agent_group', $require_agent_group)->groupBy('agent_group');
|
|
|
|
444
|
+ $require_data = $require_agent_group_data->keys()->random(count($require_agent_group))->map(function ($group) use ($require_agent_group_data) {
|
|
|
|
445
|
+ return $require_agent_group_data[$group]->random();
|
|
|
|
446
|
+ })->all();
|
|
|
|
447
|
+ //代理商组 一个组只发一个
|
|
|
|
448
|
+ $agent_group = collect($task['target'])->whereNotIn('agent_group', $require_agent_group)->groupBy('agent_group');
|
|
|
|
449
|
+ // 获取转发对象 重置num数量, array_rand数量不足会报错
|
|
|
|
450
|
+ $task['num'] = $task['num'] - count($require_agent_group);
|
|
|
|
451
|
+ $num = $task['num'] > count($agent_group) ? count($agent_group) : $task['num'];
|
|
|
|
452
|
+ $random_data = $agent_group->keys()->random($num)->map(function ($group) use ($agent_group) {
|
|
|
|
453
|
+ return $agent_group[$group]->random();
|
|
|
|
454
|
+ })->all();
|
|
|
|
455
|
+ $random_data = array_merge($require_data, $random_data);
|
|
|
|
456
|
+
|
|
|
|
457
|
+ if (empty($random_data)) {
|
|
|
|
458
|
+ $this->logChannel()->info('当前任务未发现转发对象!', ['广告任务ID:' . $task['id'], '询盘ID:' . $form->id]);
|
|
|
|
459
|
+ $form->remark = $form->remark . '当前任务未发现转发对象,广告ID: ' . $form->ad_id . '!';
|
|
|
|
460
|
+ return false;
|
|
|
|
461
|
+ }
|
|
|
|
462
|
+ $this->logChannel()->info('随机域名', array_column($random_data, 'url'));
|
|
|
|
463
|
+ foreach ($random_data as $item) {
|
|
|
|
464
|
+ $times = 1;
|
|
|
|
465
|
+ $inquiry_time = 1;
|
|
|
|
466
|
+
|
|
|
|
467
|
+ //需要多个ip访问的国家 随机2-5次访问,只有一次询盘
|
|
|
|
468
|
+ if (in_array($form->country_name, $this->multiple_ip_visit_country)) {
|
|
|
|
469
|
+ $times = mt_rand(1, 2); //随机次数
|
|
|
|
470
|
+ $inquiry_time = mt_rand(1, $times); //第几次询盘
|
|
|
|
471
|
+ $this->output('多次访问模拟:' . $times .',第' . $inquiry_time . '次询盘');
|
|
|
|
472
|
+ }
|
|
|
|
473
|
+ for ($i = 1; $i <= $times; $i++) {
|
|
|
|
474
|
+ $is_inquiry = ($inquiry_time == $i);
|
|
|
|
475
|
+ if($is_inquiry){
|
|
|
|
476
|
+ $this->output('第' . $i . '次询盘');
|
|
|
|
477
|
+ }
|
|
|
|
478
|
+ //手机号过滤
|
|
|
|
479
|
+ $phone = $form->phone;
|
|
|
|
480
|
+ $filter_phone = $this->get_rand($this->filter_phone);
|
|
|
|
481
|
+ if($filter_phone == 0){
|
|
|
|
482
|
+ $phone = trim(str_replace("+", '', $phone));
|
|
|
|
483
|
+ }elseif($filter_phone == 1){
|
|
|
|
484
|
+ $phone = '';
|
|
|
|
485
|
+ }
|
|
|
|
486
|
+
|
|
|
|
487
|
+ // 推送站点
|
|
|
|
488
|
+ $domain = $item['url'];
|
|
|
|
489
|
+ $is_v6 = $item['is_v6'];
|
|
|
|
490
|
+ $re_website = 'https://' . $domain . '/';
|
|
|
|
491
|
+
|
|
|
|
492
|
+ //urls
|
|
|
|
493
|
+ list($urls, $lang, $inquiry_product_url) = $this->getUrls($is_v6, $domain, $re_website, $form, $task);
|
|
|
|
494
|
+ if(!$urls){
|
|
|
|
495
|
+ continue;
|
|
|
|
496
|
+ }
|
|
|
|
497
|
+
|
|
|
|
498
|
+ //ip
|
|
|
|
499
|
+ $ip_data = $this->getIpData($form->country_name);
|
|
|
|
500
|
+ $ip = $ip_data->ip;
|
|
|
|
501
|
+ $country_name = $ip_data->ip_area;
|
|
|
|
502
|
+
|
|
|
|
503
|
+ //message
|
|
|
|
504
|
+ $message = '';
|
|
|
|
505
|
+ $message_id = 0;
|
|
|
|
506
|
+ $msg_lang = '';
|
|
|
|
507
|
+ if($is_inquiry) {
|
|
|
|
508
|
+ list($message, $message_id, $msg_lang) = $this->getMessage($task, $form->message, $domain, $inquiry_product_url);
|
|
|
|
509
|
+ }
|
|
|
|
510
|
+ $lang = $lang ?: $msg_lang;
|
|
|
|
511
|
+
|
|
|
|
512
|
+ $this->output('获取转发设备信息');
|
|
|
|
513
|
+ // 客户端 头信息 来源
|
|
|
|
514
|
+ $device_port = $form->email ? '1' : '2'; //1 pc 2移动端
|
|
|
|
515
|
+ $user_agent = $form->email ? Arr::random($this->pc_ua) : Arr::random($this->mobile_ua);
|
|
|
|
516
|
+ $referrer = $this->getReferer($country_name, $lang);
|
|
|
|
517
|
+ $this->output('写入数据');
|
|
|
|
518
|
+
|
|
|
|
519
|
+ $pre = 0;
|
|
|
|
520
|
+ $start_time = strtotime($form->inquiry_date);
|
|
|
|
521
|
+ if($start_time < time()){
|
|
|
|
522
|
+ $start_time = time();
|
|
|
|
523
|
+ $seconds = rand(0, 72 * 3600); // 3天内发完
|
|
|
|
524
|
+ }else{
|
|
|
|
525
|
+ $seconds = rand(100, 2 * 3600);
|
|
|
|
526
|
+ }
|
|
|
|
527
|
+ $email = '';
|
|
|
|
528
|
+ if($is_inquiry) {
|
|
|
|
529
|
+ $exists = ReInquiryDetail::where('re_website', $domain)->where('email', $form->email)->first();
|
|
|
|
530
|
+ if ($exists) {
|
|
|
|
531
|
+ $this->output('转发站点邮件已存在');
|
|
|
|
532
|
+ // continue;
|
|
|
|
533
|
+ }
|
|
|
|
534
|
+ $email = $form->email;
|
|
|
|
535
|
+ }
|
|
|
|
536
|
+ dump(date('Y-m-d H:i:s', $start_time + $seconds));
|
|
|
|
537
|
+ // 写入推送详情
|
|
|
|
538
|
+ $re_detail = ReInquiryDetail::createInquiry($task['id'], $form->id, $domain, $country_name, $ip, $form->full_name, $email, $phone, $message, $message_id, $device_port,
|
|
|
|
539
|
+ $user_agent, $referrer, $urls, $is_v6, date('Y-m-d H:i:s', $start_time + $seconds));
|
|
|
|
540
|
+ foreach ($urls as $k=>$v){
|
|
|
|
541
|
+ $pre++;
|
|
|
|
542
|
+ $seconds += rand(5,60);
|
|
|
|
543
|
+ ReInquiryDetailLog::createInquiryLog($re_detail->id, ReInquiryDetailLog::TYPE_VISIT, $pre, $v, date('Y-m-d H:i:s', $start_time + $seconds));
|
|
|
|
544
|
+ // 最后一次访问询盘 加上询盘
|
|
|
|
545
|
+ if($is_inquiry && ($k+1) == count($urls)){
|
|
|
|
546
|
+ $this->output('第' . ($k+1) . '个链接询盘');
|
|
|
|
547
|
+ $seconds += rand(30,120);
|
|
|
|
548
|
+ $pre++;
|
|
|
|
549
|
+ ReInquiryDetailLog::createInquiryLog($re_detail->id, ReInquiryDetailLog::TYPE_INQUIRY, $pre, $v, date('Y-m-d H:i:s', $start_time + $seconds));
|
|
|
|
550
|
+ }
|
|
|
|
551
|
+ }
|
|
|
|
552
|
+ }
|
|
|
|
553
|
+ }
|
|
|
|
554
|
+ return true;
|
|
|
|
555
|
+ }
|
|
|
|
556
|
+
|
|
|
|
557
|
+ public function relayShopDetail($task, $form)
|
|
|
|
558
|
+ {
|
|
|
|
559
|
+ $this->output('获取商城转发对象');
|
|
|
|
560
|
+
|
|
|
|
561
|
+ if(empty($task['shop_site'])){
|
|
|
|
562
|
+ $this->output('没有商城转发对象');
|
|
|
|
563
|
+ return 0;
|
|
|
|
564
|
+ }
|
|
|
|
565
|
+
|
|
|
|
566
|
+ $num = $task['num'] > count($task['shop_site']) ? count($task['shop_site']) : $task['num'];
|
|
|
|
567
|
+ $shop_site = collect($task['shop_site'])->random($num)->all();
|
|
|
|
568
|
+
|
|
|
|
569
|
+ foreach ($shop_site as $item) {
|
|
|
|
570
|
+ //手机号过滤
|
|
|
|
571
|
+ $phone = $form->phone;
|
|
|
|
572
|
+ // 推送站点
|
|
|
|
573
|
+ $domain = $item;
|
|
|
|
574
|
+ $re_website = 'https://' . $domain . '/';
|
|
|
|
575
|
+ $paths = ['', 'contact-us'];
|
|
|
|
576
|
+ $url = $re_website . $paths[array_rand($paths)];
|
|
|
|
577
|
+ //ip
|
|
|
|
578
|
+ $ip_data = $this->getIpData($form->country_name);
|
|
|
|
579
|
+ $ip = $ip_data->ip;
|
|
|
|
580
|
+ $country_name = $ip_data->ip_area;
|
|
|
|
581
|
+
|
|
|
|
582
|
+ //message
|
|
|
|
583
|
+ list($message, $message_id, $lang) = $this->getMessage($task, $form->message, $domain);
|
|
|
|
584
|
+
|
|
|
|
585
|
+ $device_port = $form->email ? '1' : '2'; //1 pc 2移动端
|
|
|
|
586
|
+ $user_agent = $form->email ? Arr::random($this->pc_ua) : Arr::random($this->mobile_ua);
|
|
|
|
587
|
+ $referrer = $this->getReferer($country_name, $lang);
|
|
|
|
588
|
+
|
|
|
|
589
|
+ $start_time = strtotime($form->inquiry_date);
|
|
|
|
590
|
+ if($start_time < time()){
|
|
|
|
591
|
+ $start_time = time();
|
|
|
|
592
|
+ $seconds = rand(0, 48 * 3600); // 开始时间 从5-2小时后开始
|
|
|
|
593
|
+ }else{
|
|
|
|
594
|
+ $seconds = rand(100, 2 * 3600);
|
|
|
|
595
|
+ }
|
|
|
|
596
|
+ dump(date('Y-m-d H:i:s', $start_time + $seconds));
|
|
|
|
597
|
+ $exists = ReInquiryDetail::where('re_website', $domain)->where('email', $form->email)->first();
|
|
|
|
598
|
+ if($exists){
|
|
|
|
599
|
+ $this->output('转发站点邮件已存在');
|
|
|
|
600
|
+ continue;
|
|
|
|
601
|
+ }
|
|
|
|
602
|
+ $re_detail = ReInquiryDetail::createInquiry($task['id'], $form->id, $domain, $country_name, $ip, $form->full_name, $form->email, $phone, $message, $message_id,
|
|
|
|
603
|
+ $device_port, $user_agent, $referrer, [$url], 0, date('Y-m-d H:i:s', $start_time + $seconds), ReInquiryDetail::STATUS_INIT, 2);
|
|
|
|
604
|
+
|
|
|
|
605
|
+ ReInquiryDetailLog::createInquiryLog($re_detail->id, ReInquiryDetailLog::TYPE_INQUIRY, 1, $url, date('Y-m-d H:i:s', $start_time + $seconds));
|
|
|
|
606
|
+ }
|
|
|
|
607
|
+ return true;
|
|
|
|
608
|
+ }
|
|
|
|
609
|
+
|
|
|
|
610
|
+
|
|
|
|
611
|
+ public function relayFobDetail($task, $form)
|
|
|
|
612
|
+ {
|
|
|
|
613
|
+ $this->output('获取FOB转发对象');
|
|
|
|
614
|
+
|
|
|
|
615
|
+ if(empty($task['fob_pro'])){
|
|
|
|
616
|
+ $this->output('没有FOB转发对象');
|
|
|
|
617
|
+ return 0;
|
|
|
|
618
|
+ }
|
|
|
|
619
|
+
|
|
|
|
620
|
+ foreach ($task['fob_pro'] as $item) {
|
|
|
|
621
|
+ //手机号过滤
|
|
|
|
622
|
+ $phone = $form->phone;
|
|
|
|
623
|
+ // 推送站点
|
|
|
|
624
|
+ $postid = $item;
|
|
|
|
625
|
+ //message
|
|
|
|
626
|
+ list($message, $message_id, $lang) = $this->getMessage($task, $form->message, $postid);
|
|
|
|
627
|
+
|
|
|
|
628
|
+ $device_port = $form->email ? '1' : '2'; //1 pc 2移动端
|
|
|
|
629
|
+ $user_agent = $form->email ? Arr::random($this->pc_ua) : Arr::random($this->mobile_ua);
|
|
|
|
630
|
+
|
|
|
|
631
|
+ $start_time = strtotime($form->inquiry_date);
|
|
|
|
632
|
+ if($start_time < time()){
|
|
|
|
633
|
+ $start_time = time();
|
|
|
|
634
|
+ $seconds = rand(0, 10 * 3600); // 开始时间 从5-2小时后开始
|
|
|
|
635
|
+ }else{
|
|
|
|
636
|
+ $seconds = rand(100, 2 * 3600);
|
|
|
|
637
|
+ }
|
|
|
|
638
|
+ dump(date('Y-m-d H:i:s', $start_time + $seconds));
|
|
|
|
639
|
+ $exists = ReInquiryDetail::where('re_website', $postid)->where('email', $form->email)->first();
|
|
|
|
640
|
+ if($exists){
|
|
|
|
641
|
+ $this->output('转发站点邮件已存在');
|
|
|
|
642
|
+ continue;
|
|
|
|
643
|
+ }
|
|
|
|
644
|
+ $re_detail = ReInquiryDetail::createInquiry($task['id'], $form->id, $postid, $country_name??'', $ip??'', $form->full_name, $form->email, $phone,
|
|
|
|
645
|
+ $message, $message_id, $device_port, $user_agent, $referrer??'', [$postid], 0, date('Y-m-d H:i:s', $start_time + $seconds), ReInquiryDetail::STATUS_INIT, 3);
|
|
|
|
646
|
+
|
|
|
|
647
|
+ ReInquiryDetailLog::createInquiryLog($re_detail->id, ReInquiryDetailLog::TYPE_INQUIRY, 1, $postid, date('Y-m-d H:i:s', $start_time + $seconds));
|
|
|
|
648
|
+ }
|
|
|
|
649
|
+ return true;
|
|
|
|
650
|
+ }
|
|
|
|
651
|
+
|
|
|
|
652
|
+ public function getIpData($country_name){
|
|
|
|
653
|
+ $this->output('获取转发ip');
|
|
|
|
654
|
+ $country = $country_name;
|
|
|
|
655
|
+ // 有国家 通过国家查询, 如果没有获取到就随机获取
|
|
|
|
656
|
+ $where = [];
|
|
|
|
657
|
+ $country && $where['ip_area'] = $country;
|
|
|
|
658
|
+ $ip_data = DB::table('gl_xunpan_ipdata')->where($where)->inRandomOrder()->first();
|
|
|
|
659
|
+ if (empty($ip_data)) {
|
|
|
|
660
|
+ $ip_data = DB::table('gl_xunpan_ipdata')->inRandomOrder()->first();
|
|
|
|
661
|
+ }
|
|
|
|
662
|
+ return $ip_data;
|
|
|
|
663
|
+ }
|
|
|
|
664
|
+
|
|
|
|
665
|
+ public function getMessage($task, $message, $domain, $inquiry_product_url = ''){
|
|
|
|
666
|
+ $this->output('转发内容');
|
|
|
|
667
|
+ $form_message = $message;
|
|
|
|
668
|
+ $message_id = 0;
|
|
|
|
669
|
+
|
|
|
|
670
|
+ // TODO 当原始询盘内容长度大于15个字符, 60%几率直接发送原始内容。
|
|
|
|
671
|
+ if (strlen($message) >= 15) {
|
|
|
|
672
|
+ $not_use_probability = AiCommand::where('key', 'fb_inquiry_text')->value('not_use_probability');
|
|
|
|
673
|
+ $randomNumber = rand(0, 100);
|
|
|
|
674
|
+ if($randomNumber < $not_use_probability){
|
|
|
|
675
|
+ //原内容非英语,转为对应语种
|
|
|
|
676
|
+ if (is_numeric($form_message)) { //数字会被识别为中文
|
|
|
|
677
|
+ $lang = 'en';
|
|
|
|
678
|
+ } else {
|
|
|
|
679
|
+ $translateSl = Translate::translateSl($form_message);
|
|
|
|
680
|
+ $lang = $translateSl['texts']['sl'] ?? 'en';
|
|
|
|
681
|
+ }
|
|
|
|
682
|
+ return [$message, $message_id, $lang??''];
|
|
|
|
683
|
+ }
|
|
|
|
684
|
+ }
|
|
|
|
685
|
+
|
|
|
|
686
|
+ //开启文案替换
|
|
|
|
687
|
+ if ($task['is_replace_text'] == 2) {
|
|
|
|
688
|
+ //AI生成
|
|
|
|
689
|
+ $error = 0;
|
|
|
|
690
|
+ while ($error<3){
|
|
|
|
691
|
+ $message = $this->ai_send($task['ai_param'], $message, $inquiry_product_url);
|
|
|
|
692
|
+ if(!$message){
|
|
|
|
693
|
+ $this->output('AI文案生成失败');
|
|
|
|
694
|
+ $error++;
|
|
|
|
695
|
+ if($error==2){
|
|
|
|
696
|
+ $task['is_replace_text'] = 1;
|
|
|
|
697
|
+ $this->output('AI文案生成失败,使用文案库');
|
|
|
|
698
|
+ }
|
|
|
|
699
|
+ }else{
|
|
|
|
700
|
+ break;
|
|
|
|
701
|
+ }
|
|
|
|
702
|
+ }
|
|
|
|
703
|
+ }
|
|
|
|
704
|
+ if ($task['is_replace_text'] == 1 || strlen($message) <= 4) {
|
|
|
|
705
|
+ //配置文案库替换或者字符少于4个,直接替换文案
|
|
|
|
706
|
+ $use_ids = ReInquiryDetail::where(['re_website' => $domain])->where('status', '<>', ReInquiryDetail::STATUS_FAIL)->pluck('text_id')->toArray();
|
|
|
|
707
|
+ $text = ReInquiryText::whereNotIn('id', $use_ids)->where('status', ReInquiryText::STATUS_USABLE)->inRandomOrder()->first();
|
|
|
|
708
|
+ $message = $text->content;
|
|
|
|
709
|
+ $message_id = $text->id;
|
|
|
|
710
|
+ // 获取后,使用次数+1
|
|
|
|
711
|
+ $text->use_time += 1;
|
|
|
|
712
|
+ $text->save();
|
|
|
|
713
|
+
|
|
|
|
714
|
+ //原内容非英语,转为对应语种
|
|
|
|
715
|
+ if (is_numeric($form_message)) { //数字会被识别为中文
|
|
|
|
716
|
+ $lang = 'en';
|
|
|
|
717
|
+ } else {
|
|
|
|
718
|
+ $translateSl = Translate::translateSl($form_message);
|
|
|
|
719
|
+ $lang = $translateSl['texts']['sl'] ?? 'en';
|
|
|
|
720
|
+ }
|
|
|
|
721
|
+
|
|
|
|
722
|
+ if ($lang != 'en' && !Str::contains($lang, 'zh')) {
|
|
|
|
723
|
+ $message = Translate::tran($message, $lang);
|
|
|
|
724
|
+ }
|
|
|
|
725
|
+ }
|
|
|
|
726
|
+ return [$message, $message_id, $lang??''];
|
|
|
|
727
|
+ }
|
|
|
|
728
|
+
|
|
|
|
729
|
+ public function getUrls($is_v6, $domain, $re_website, $form, $task){
|
|
|
|
730
|
+ $this->output('转发对象:' . $domain);
|
|
|
|
731
|
+ $this->output('获取转发链接');
|
|
|
|
732
|
+ // v6:有邮箱推送主站,没有邮箱推送AMP站;v5:仅推送有邮箱到主站
|
|
|
|
733
|
+ $lang = '';
|
|
|
|
734
|
+ if ($is_v6) {
|
|
|
|
735
|
+ // 获取语种, 6.0是可以确定语种的
|
|
|
|
736
|
+ $project = Project::getProjectByDomain($domain);
|
|
|
|
737
|
+ if (empty($project)) {
|
|
|
|
738
|
+ $this->logChannel()->info('广告任务ID:' . $task['id'] . ', 转发对象:' . $re_website . '非v6链接,转发失败;', ['广告任务ID:' . $task['id'], '询盘ID:' . $form->id]);
|
|
|
|
739
|
+ return [[], $lang];
|
|
|
|
740
|
+ }
|
|
|
|
741
|
+ $lang = WebLanguage::getLangById($project->main_lang_id ?? 1)['short'];
|
|
|
|
742
|
+
|
|
|
|
743
|
+ // 获取访问明细和着陆页
|
|
|
|
744
|
+ $product_url = $this->getLinksFromSitemap($re_website . 'product_sitemap.xml');
|
|
|
|
745
|
+ $product_cate_url = $this->getLinksFromSitemap($re_website . 'product_category_sitemap.xml');
|
|
|
|
746
|
+ $keywords_url = $this->getLinksFromSitemap($re_website . 'product_keywords_sitemap.xml');
|
|
|
|
747
|
+ $page_url = $this->getLinksFromSitemap($re_website . 'page_sitemap.xml');
|
|
|
|
748
|
+ } else {
|
|
|
|
749
|
+ if($form->email){
|
|
|
|
750
|
+ //通过sitemap拿访问页面
|
|
|
|
751
|
+ $product_url = $this->getLinksFromSitemap($re_website . 'sitemap_post.xml');
|
|
|
|
752
|
+ $product_cate_url = $this->getLinksFromSitemap($re_website . 'sitemap_category.xml');
|
|
|
|
753
|
+ $keywords_url = $this->getLinksFromSitemap($re_website . 'sitemap_post_tag.xml');
|
|
|
|
754
|
+ $page_url = $this->getLinksFromSitemap($re_website . 'sitemap_page.xml');
|
|
|
|
755
|
+ }else{
|
|
|
|
756
|
+ //m站先就往contact-us着陆
|
|
|
|
757
|
+ $product_url = $product_cate_url = $keywords_url = [];
|
|
|
|
758
|
+ $page_url = [$re_website . 'contact-us/'];
|
|
|
|
759
|
+ }
|
|
|
|
760
|
+ }
|
|
|
|
761
|
+
|
|
|
|
762
|
+ // 所有可用url
|
|
|
|
763
|
+ $urls = $inquiry_urls = [];
|
|
|
|
764
|
+ //入口url 首页30%,单页10%,聚合页60%
|
|
|
|
765
|
+ $type = getRandByRatio([30,10,60]);
|
|
|
|
766
|
+ $inlet = $re_website;
|
|
|
|
767
|
+ $type == 1 && $inlet = $page_url ? Arr::random($page_url) : $re_website;
|
|
|
|
768
|
+ $type == 2 && $inlet = $keywords_url ? Arr::random($keywords_url) : $re_website;
|
|
|
|
769
|
+ $urls[] = $inquiry_urls[] = $inlet;
|
|
|
|
770
|
+ $all_urls = array_merge($urls, $product_url, $product_cate_url, $keywords_url, $page_url);
|
|
|
|
771
|
+ $inquiry_urls = array_merge($urls, $product_cate_url, $keywords_url, $page_url);
|
|
|
|
772
|
+
|
|
|
|
773
|
+ // 随机访问1-6个页面
|
|
|
|
774
|
+ $deep = rand(1,6);
|
|
|
|
775
|
+ if($deep > 2) {
|
|
|
|
776
|
+ $visit_urls = Arr::random($all_urls, rand(1, count($all_urls) > 4 ? 4 : count($all_urls)));
|
|
|
|
777
|
+ $urls = array_merge($urls, $visit_urls);
|
|
|
|
778
|
+ }
|
|
|
|
779
|
+ if($deep > 1) {
|
|
|
|
780
|
+ // 推送着落页只能是 首页、产品分类、单页面、聚合页
|
|
|
|
781
|
+ if (!in_array(end($urls), $inquiry_urls)) {
|
|
|
|
782
|
+ $urls[] = Arr::random($inquiry_urls);
|
|
|
|
783
|
+ }
|
|
|
|
784
|
+ }
|
|
|
|
785
|
+ //着陆页是否是产品页面或产品列表页
|
|
|
|
786
|
+ $inquiry_product_url = '';
|
|
|
|
787
|
+ if(in_array(Arr::last($urls), $product_url) || in_array(Arr::last($urls), $product_cate_url)){
|
|
|
|
788
|
+ $inquiry_product_url = Arr::last($urls);
|
|
|
|
789
|
+ }
|
|
|
|
790
|
+
|
|
|
|
791
|
+ return [$urls, $lang, $inquiry_product_url];
|
|
|
|
792
|
+ }
|
|
|
|
793
|
+ /**
|
|
|
|
794
|
+ * 获取待处理询盘表单
|
|
|
|
795
|
+ * @param int $num
|
|
|
|
796
|
+ * @return mixed
|
|
|
|
797
|
+ */
|
|
|
|
798
|
+ public function getInquiry($num = 10)
|
|
|
|
799
|
+ {
|
|
|
|
800
|
+ $result = ReInquiryForm::where(['status' => ReInquiryForm::STATUS_INIT])->orderBy('id', 'asc')->limit($num)->get();
|
|
|
|
801
|
+ return $result;
|
|
|
|
802
|
+ }
|
|
|
|
803
|
+
|
|
|
|
804
|
+ /**
|
|
|
|
805
|
+ * 获取广告任务配置数据
|
|
|
|
806
|
+ * @param $ad_id
|
|
|
|
807
|
+ * @return array
|
|
|
|
808
|
+ */
|
|
|
|
809
|
+ public function getAdTask($ad_id)
|
|
|
|
810
|
+ {
|
|
|
|
811
|
+ $cache_key = 'inquiry_ads_tasks';
|
|
|
|
812
|
+ $ads = Cache::get($cache_key, function () use ($cache_key) {
|
|
|
|
813
|
+ $ads = ReInquiryTask::where(['status' => ReInquiryTask::STATUS_OPEN])->get(['id', 'ad_id', 'num', 'target', 'is_replace_text', 'ai_param', 'shop_site', 'fob_pro']);
|
|
|
|
814
|
+ $array = [];
|
|
|
|
815
|
+ foreach ($ads as $key=>$val) {
|
|
|
|
816
|
+ $ad_ids = explode(',', $val['ad_id']);
|
|
|
|
817
|
+ foreach ($ad_ids as $ad_id){
|
|
|
|
818
|
+ $array[$ad_id][] = $val;
|
|
|
|
819
|
+ }
|
|
|
|
820
|
+ }
|
|
|
|
821
|
+ if ($array)
|
|
|
|
822
|
+ Cache::put($cache_key, $array, 60);
|
|
|
|
823
|
+ return $array;
|
|
|
|
824
|
+ });
|
|
|
|
825
|
+ return empty($ads[$ad_id]) ? [] : $ads[$ad_id];
|
|
|
|
826
|
+ }
|
|
|
|
827
|
+
|
|
|
|
828
|
+ /**
|
|
|
|
829
|
+ * 获取头信息
|
|
|
|
830
|
+ * @param $ip_area
|
|
|
|
831
|
+ * @param $lang
|
|
|
|
832
|
+ * @return int|string
|
|
|
|
833
|
+ */
|
|
|
|
834
|
+ public function getReferer($ip_area, $lang)
|
|
|
|
835
|
+ {
|
|
|
|
836
|
+ if($lang == 'ru'){
|
|
|
|
837
|
+ return $this->get_rand($this->eylyzb);
|
|
|
|
838
|
+ }
|
|
|
|
839
|
+ if($ip_area == '美国'){
|
|
|
|
840
|
+ $referer = $this->get_rand($this->lyzb);
|
|
|
|
841
|
+ }else{
|
|
|
|
842
|
+ $referer = 'https://www.google.com/';
|
|
|
|
843
|
+ $suffix = array_search($ip_area, $this->suffix);
|
|
|
|
844
|
+ if($suffix){
|
|
|
|
845
|
+ $res_qtzb = $this->get_rand($this->otherzb);
|
|
|
|
846
|
+ if($res_qtzb == 1){
|
|
|
|
847
|
+ $referer = 'https://www.google.'.$suffix.'/';
|
|
|
|
848
|
+ }
|
|
|
|
849
|
+ }
|
|
|
|
850
|
+ }
|
|
|
|
851
|
+ return $referer;
|
|
|
|
852
|
+ }
|
|
|
|
853
|
+
|
|
|
|
854
|
+ /**
|
|
|
|
855
|
+ * 概率算法
|
|
|
|
856
|
+ * @param $proArr
|
|
|
|
857
|
+ * @return int|string
|
|
|
|
858
|
+ */
|
|
|
|
859
|
+ protected function get_rand($proArr)
|
|
|
|
860
|
+ {
|
|
|
|
861
|
+ $result = '';
|
|
|
|
862
|
+ $proSum = array_sum($proArr);
|
|
|
|
863
|
+ foreach ($proArr as $key => $proCur) {
|
|
|
|
864
|
+ $randNum = mt_rand(1, $proSum);
|
|
|
|
865
|
+ if ($randNum <= $proCur) {
|
|
|
|
866
|
+ $result = $key;
|
|
|
|
867
|
+ break;
|
|
|
|
868
|
+ } else {
|
|
|
|
869
|
+ $proSum -= $proCur;
|
|
|
|
870
|
+ }
|
|
|
|
871
|
+ }
|
|
|
|
872
|
+ unset ($proArr);
|
|
|
|
873
|
+ return $result;
|
|
|
|
874
|
+ }
|
|
|
|
875
|
+
|
|
|
|
876
|
+ /**
|
|
|
|
877
|
+ * 获取sitemap内容
|
|
|
|
878
|
+ * @param $sitemapUrl
|
|
|
|
879
|
+ * @return array|mixed
|
|
|
|
880
|
+ */
|
|
|
|
881
|
+ function getLinksFromSitemap($sitemapUrl) {
|
|
|
|
882
|
+ try {
|
|
|
|
883
|
+ //忽略cert证书 先下载到临时文件
|
|
|
|
884
|
+ $result = Http::withoutVerifying()->get($sitemapUrl)->body();
|
|
|
|
885
|
+ $tempFilePath = tempnam(sys_get_temp_dir(), 'remote_file_');
|
|
|
|
886
|
+ file_put_contents($tempFilePath, $result);
|
|
|
|
887
|
+ $xml = simplexml_load_file($tempFilePath);
|
|
|
|
888
|
+ $links = [];
|
|
|
|
889
|
+ foreach ($xml->url as $url) {
|
|
|
|
890
|
+ $loc = (string) $url->loc;
|
|
|
|
891
|
+ if(!Str::contains($loc, ['404', 'thanks', 'test'])){
|
|
|
|
892
|
+ $links[] = $loc;
|
|
|
|
893
|
+ }
|
|
|
|
894
|
+ }
|
|
|
|
895
|
+ //随机取20个
|
|
|
|
896
|
+ $total = count($links);
|
|
|
|
897
|
+ return Arr::random($links, $total > 20 ? 20 : $total);
|
|
|
|
898
|
+ }catch (\Exception $e){
|
|
|
|
899
|
+ echo date('Y-m-d H:i:s') . 'sitemap获取失败:' . $e->getMessage() . PHP_EOL;
|
|
|
|
900
|
+ return $links??[];
|
|
|
|
901
|
+ }
|
|
|
|
902
|
+ }
|
|
|
|
903
|
+
|
|
|
|
904
|
+ public function ai_send($ai_param, $incontent, $inquiry_product_url)
|
|
|
|
905
|
+ {
|
|
|
|
906
|
+ $ai_command = AiCommand::where('key', 'fb_inquiry_text')->value('ai');
|
|
|
|
907
|
+ if (!$ai_command) {
|
|
|
|
908
|
+ return '';
|
|
|
|
909
|
+ }
|
|
|
|
910
|
+ $translateSl = Translate::translateSl($incontent);
|
|
|
|
911
|
+ $lang = $translateSl['texts']['sl'] ?? 'en';
|
|
|
|
912
|
+ if ($lang == 'en' || $lang == 'ja' || $lang == 'ko' || Str::contains($lang, 'zh')) {
|
|
|
|
913
|
+ $language = '英文';
|
|
|
|
914
|
+ $lang = 'en';
|
|
|
|
915
|
+ }else{
|
|
|
|
916
|
+ $language = Translate::getTls($lang);
|
|
|
|
917
|
+ }
|
|
|
|
918
|
+
|
|
|
|
919
|
+
|
|
|
|
920
|
+
|
|
|
|
921
|
+ //着陆页是否是产品页面或产品列表页
|
|
|
|
922
|
+ if($inquiry_product_url){
|
|
|
|
923
|
+ $title = Common::getUrlTitle($inquiry_product_url);
|
|
|
|
924
|
+ if($title){
|
|
|
|
925
|
+ $ai_command = str_replace('{mkeywords}', $title, $ai_command);
|
|
|
|
926
|
+ }
|
|
|
|
927
|
+ }
|
|
|
|
928
|
+ $ai_command = str_replace('{mkeywords}', Arr::random(explode("\r\n", $ai_param['mkeywords'])), $ai_command);
|
|
|
|
929
|
+ $ai_command = str_replace('{incontent}', Arr::random(explode("\r\n", $incontent)), $ai_command);
|
|
|
|
930
|
+ $ai_command = str_replace('{characters}', Arr::random(explode("\r\n", $ai_param['characters'])), $ai_command);
|
|
|
|
931
|
+// $ai_command = str_replace('{language}', Arr::random(explode("\r\n", $language)), $ai_command);
|
|
|
|
932
|
+ $ai_command = str_replace('{language}', '英语', $ai_command); //输出英文 后面再翻译
|
|
|
|
933
|
+ $ai_command = str_replace('{inkeywords}', Arr::random(explode("\r\n", $ai_param['inkeywords'])), $ai_command);
|
|
|
|
934
|
+ $ai_command = str_replace('{suoxie}', Arr::random(explode("\r\n", $ai_param['suoxie'])), $ai_command);
|
|
|
|
935
|
+ //中括号里的根据概率使用
|
|
|
|
936
|
+ preg_match_all("/\[([^\]]+)\]/", $ai_command, $matches);
|
|
|
|
937
|
+ foreach ($matches[1] as $k => $match){
|
|
|
|
938
|
+ //按比例使用
|
|
|
|
939
|
+ $matche_arr = explode('|', $match);
|
|
|
|
940
|
+ $percentage = intval(trim($matche_arr[0], "%"));
|
|
|
|
941
|
+ if(rand(1,100) <= $percentage){
|
|
|
|
942
|
+ //使用
|
|
|
|
943
|
+ $ai_command = str_replace($matches[0][$k], $matche_arr[1], $ai_command);
|
|
|
|
944
|
+ }else{
|
|
|
|
945
|
+ //删除中括号
|
|
|
|
946
|
+ $ai_command = str_replace($matches[0][$k], '', $ai_command);
|
|
|
|
947
|
+ }
|
|
|
|
948
|
+ }
|
|
|
|
949
|
+
|
|
|
|
950
|
+ $text = Gpt::instance()->openai_chat_qqs($ai_command);
|
|
|
|
951
|
+ if ($lang != 'en' && !Str::contains($lang, 'zh')) {
|
|
|
|
952
|
+ $text = Translate::tran($text, $lang);
|
|
|
|
953
|
+ }
|
|
|
|
954
|
+ $this->logChannel()->info("AI询盘文案", [$ai_command, $text]);
|
|
|
|
955
|
+ return Common::deal_str($text);
|
|
|
|
956
|
+ }
|
|
|
|
957
|
+
|
|
|
|
958
|
+ /**
|
|
|
|
959
|
+ * @return \Psr\Log\LoggerInterface
|
|
|
|
960
|
+ */
|
|
|
|
961
|
+ public function logChannel()
|
|
|
|
962
|
+ {
|
|
|
|
963
|
+ return Log::channel('inquiry_relay');
|
|
|
|
964
|
+ }
|
|
|
|
965
|
+
|
|
|
|
966
|
+ public function output($message)
|
|
|
|
967
|
+ {
|
|
|
|
968
|
+ echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
|
|
|
|
969
|
+ }
|
|
|
|
970
|
+} |