作者 刘锟

Merge remote-tracking branch 'origin/master' into akun

@@ -38,7 +38,6 @@ class SyncFile extends Command @@ -38,7 +38,6 @@ class SyncFile extends Command
38 echo date('Y-m-d H:i:s') . '编辑的path为:'. $v['path'] .',主键id:'. $v['id'] . PHP_EOL; 38 echo date('Y-m-d H:i:s') . '编辑的path为:'. $v['path'] .',主键id:'. $v['id'] . PHP_EOL;
39 $errorFileModel->edit(['status'=>1],['id'=>$v['id']]); 39 $errorFileModel->edit(['status'=>1],['id'=>$v['id']]);
40 } 40 }
41 - gc_collect_cycles();  
42 } 41 }
43 echo date('Y-m-d H:i:s') . '编辑的end为:' . PHP_EOL; 42 echo date('Y-m-d H:i:s') . '编辑的end为:' . PHP_EOL;
44 return true; 43 return true;
  1 +<?php
  2 +
  3 +namespace App\Console\Commands\Sync;
  4 +
  5 +
  6 +use App\Exceptions\InquiryFilterException;
  7 +use App\Models\Project\Project;
  8 +use App\Models\SyncSubmitTask\SyncSubmitTaskZbj as SyncSubmitTaskModel;
  9 +use App\Services\SyncSubmitTaskService;
  10 +use Illuminate\Console\Command;
  11 +use Illuminate\Support\Facades\DB;
  12 +use Illuminate\Support\Facades\Redis;
  13 +use Illuminate\Support\Facades\Schema;
  14 +use Illuminate\Support\Str;
  15 +
  16 +/**
  17 + *
  18 + * Class SyncSubmitTask
  19 + * @package App\Console\Commands
  20 + * @author zbj
  21 + * @date 2023/11/28
  22 + */
  23 +class SyncSubmitTaskZbj extends Command
  24 +{
  25 +
  26 + protected $signature = 'sync_submit_task_zbj';
  27 + protected $description = '询盘、访问异步任务';
  28 +
  29 + public function handle()
  30 + {
  31 + $backup = false;
  32 + while (true) {
  33 + $task_id = $this->getTaskId();
  34 + if ($task_id > 2000000) {
  35 + $backup = true;
  36 + }
  37 + if (empty($task_id)) {
  38 + if ($backup) {
  39 + $this->backup();
  40 + $backup = false;
  41 + }
  42 + sleep(5);
  43 + continue;
  44 + }
  45 + $this->output('任务' . $task_id . '开始');
  46 + $task_info = SyncSubmitTaskModel::find($task_id);
  47 + if (empty($task_info) || $task_info->status != 3) {
  48 + $this->output('任务不存在或者已执行');
  49 + continue;
  50 + }
  51 + try {
  52 + $project = Project::getProjectByDomain($task_info['data']['domain'] ?? '');
  53 + $task_info->project_id = $project->id;
  54 +
  55 + SyncSubmitTaskService::handler($task_info, $task_info->created_at);
  56 + $task_info->status = 1;
  57 + $task_info->save();
  58 +
  59 + $this->output('任务完成');
  60 + } catch (InquiryFilterException $e) {
  61 + $task_info->status = 1;
  62 + $task_info->is_filtered = 1;
  63 + $task_info->remark = $e->getMessage();
  64 + $task_info->save();
  65 +
  66 + $this->output('任务完成');
  67 + } catch (\Exception $e) {
  68 + $task_info->retry = $task_info->retry + 1;
  69 + if ($task_info->retry >= 3) {
  70 + $task_info->status = 2;
  71 + $task_info->remark = Str::substr($e->getMessage(), 0, 200);
  72 + } else {
  73 + Redis::lpush('sync_submit_task_zbj', $task_id);
  74 + }
  75 + $task_info->save();
  76 +
  77 + $this->output('任务失败:' . $e->getMessage());
  78 + }
  79 + }
  80 + }
  81 +
  82 + public function getTaskId()
  83 + {
  84 + $task_id = Redis::rpop('sync_submit_task_zbj');
  85 + if (empty($task_id)) {
  86 + $ids = SyncSubmitTaskModel::where('status', 3)->limit(100)->pluck('id');
  87 + foreach ($ids as $id) {
  88 + Redis::lpush('sync_submit_task_zbj', $id);
  89 + }
  90 + $task_id = Redis::rpop('sync_submit_task_zbj');
  91 + }
  92 + return $task_id;
  93 + }
  94 +
  95 + /**
  96 + * 输出处理日志
  97 + */
  98 + public function output($message): bool
  99 + {
  100 + echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
  101 + return true;
  102 + }
  103 +
  104 + /**
  105 + * 备份数据
  106 + * @author zbj
  107 + * @date 2024/1/23
  108 + */
  109 + public function backup()
  110 + {
  111 + DB::beginTransaction();
  112 + try {
  113 + $table = (new SyncSubmitTaskModel())->getTable();
  114 + $new_table = $table . '_backup_' . date('Ymd');
  115 +
  116 + //重命名当前表
  117 + Schema::rename($table, $new_table);
  118 + //克隆表数据
  119 + DB::statement('CREATE TABLE ' . $table . ' LIKE ' . $new_table);
  120 +
  121 + DB::commit();
  122 +
  123 + $this->output('数据备份成功');
  124 + } catch (\Exception $e) {
  125 + $this->output('数据备份失败' . $e->getMessage());
  126 + DB::rollBack();
  127 + }
  128 + return true;
  129 + }
  130 +}
@@ -10,11 +10,16 @@ use App\Models\HomeCount\Count; @@ -10,11 +10,16 @@ use App\Models\HomeCount\Count;
10 use App\Models\Inquiry\InquiryFormData; 10 use App\Models\Inquiry\InquiryFormData;
11 use App\Models\Nav\BNav; 11 use App\Models\Nav\BNav;
12 use App\Models\Nav\BNavGroup; 12 use App\Models\Nav\BNavGroup;
  13 +use App\Models\Project\OnlineCheck;
13 use App\Models\Project\Project; 14 use App\Models\Project\Project;
14 use App\Models\SyncSubmitTask\SyncSubmitTask as SyncSubmitTaskModel; 15 use App\Models\SyncSubmitTask\SyncSubmitTask as SyncSubmitTaskModel;
15 use App\Models\WebSetting\Translate as TranslateModel; 16 use App\Models\WebSetting\Translate as TranslateModel;
  17 +use App\Models\WebSetting\WebLanguage;
16 use App\Services\ProjectServer; 18 use App\Services\ProjectServer;
  19 +use Carbon\Carbon;
17 use Illuminate\Console\Command; 20 use Illuminate\Console\Command;
  21 +use Illuminate\Support\Facades\DB;
  22 +use Illuminate\Support\Facades\Redis;
18 23
19 /** 24 /**
20 * Class Test 25 * Class Test
@@ -53,6 +58,19 @@ class Test extends Command @@ -53,6 +58,19 @@ class Test extends Command
53 */ 58 */
54 public function handle() 59 public function handle()
55 { 60 {
  61 + $date = '2024-05-16';
  62 + $list = $this->getProjectList();
  63 + foreach ($list as $item){
  64 + ProjectServer::useProject($item['project_id']);
  65 + //pv统计
  66 + $pv_num = $this->pv_num($date);
  67 + //ip统计
  68 + $ip_num = $this->ip_num($date);
  69 +
  70 + echo $item['project_id'] . ',pv:' . $pv_num . ',ip:' . $ip_num . PHP_EOL;
  71 + }
  72 + exit;
  73 +
56 74
57 $i=0; 75 $i=0;
58 while (true){ 76 while (true){
@@ -167,4 +185,78 @@ class Test extends Command @@ -167,4 +185,78 @@ class Test extends Command
167 $arr['country'] = json_encode($top20); 185 $arr['country'] = json_encode($top20);
168 return $arr; 186 return $arr;
169 } 187 }
  188 +
  189 + protected function getProjectList($type = 1){
  190 + $ru_lang_id = WebLanguage::getIdByLang('ru');
  191 +
  192 + //推广项目
  193 + $list = Project::with('domainInfo')
  194 + ->leftJoin('gl_project_deploy_optimize as pdo', 'pdo.project_id', '=', 'gl_project.id')
  195 + ->leftJoin('gl_project_online_check as poc', 'poc.project_id', '=', 'gl_project.id')
  196 + ->where('pdo.domain', '>', 0)
  197 + ->where('poc.qa_status', OnlineCheck::STATUS_ONLINE_TRUE)
  198 + ->whereIn('gl_project.type', [Project::TYPE_TWO, Project::TYPE_FOUR])
  199 + ->where('gl_project.is_upgrade', 0) //非升级项目
  200 + ->where('gl_project.main_lang_id', '<>', $ru_lang_id) //非俄语站
  201 + ->where(function ($query) use ($type) {
  202 + if($type == 1){
  203 + //1-3个月项目
  204 + $startTime = Carbon::now()->addMonths(-4)->toDateString();
  205 + $endTime = Carbon::now()->addMonths(-1)->toDateString();
  206 + $query->whereBetween('pdo.start_date', [$startTime,$endTime]);
  207 + }elseif($type == 2){
  208 + //4-8个月项目
  209 + $startTime = Carbon::now()->addMonths(-9)->startOfDay()->toDateTimeString();
  210 + $endTime = Carbon::now()->addMonths(-4)->endOfDay()->toDateTimeString();
  211 + $query->whereBetween('pdo.start_date', [$startTime,$endTime]);
  212 + }else{
  213 + //大于9个月项目
  214 + $startTime = Carbon::now()->addMonths(-9)->startOfDay()->toDateTimeString();
  215 + $query->where('pdo.start_date', '<', $startTime);
  216 + }
  217 + })->select(['pdo.project_id','gl_project.main_lang_id','gl_project.id'])
  218 + ->orderBy('project_id')
  219 + ->get();
  220 + //其他地方在引流的域名
  221 + $other = DB::connection('projects_mysql')->table('projects')->where('switch', 1)->pluck('domain')->toArray();
  222 + $data = [];
  223 + foreach ($list as $project) {
  224 + $lang = WebLanguage::getLangById($project['main_lang_id']??1)['short'];
  225 + if(empty($project->domainInfo['domain'])){
  226 + continue;
  227 + }
  228 + //其他地方在引流就不再引流了
  229 + if(in_array($project->domainInfo['domain'], $other)){
  230 + continue;
  231 + }
  232 + $data[] = [
  233 + 'project_id' => $project['project_id'],
  234 + 'domain' => 'https://' . $project->domainInfo['domain'] . '/',
  235 + 'lang' => $lang
  236 + ];
  237 + }
  238 + return $data;
  239 + }
  240 + /**
  241 + * @name :(统计pv)pv_num
  242 + * @author :lyh
  243 + * @method :post
  244 + * @time :2023/6/14 15:40
  245 + */
  246 + public function pv_num($yesterday){
  247 + $pv = DB::connection('custom_mysql')->table('gl_customer_visit_item')->where('updated_date', $yesterday)->count();
  248 + return $pv;
  249 + }
  250 +
  251 + /**
  252 + * @name :(统计ip)ip_num
  253 + * @author :lyh
  254 + * @method :post
  255 + * @time :2023/6/14 15:40
  256 + */
  257 + public function ip_num($yesterday)
  258 + {
  259 + $ip = DB::connection('custom_mysql')->table('gl_customer_visit')->where('updated_date', $yesterday)->count();
  260 + return $ip;
  261 + }
170 } 262 }
  1 +<?php
  2 +
  3 +namespace App\Console\Commands\WebTraffic;
  4 +
  5 +use App\Helper\Arr;
  6 +use App\Models\HomeCount\Count;
  7 +use App\Models\Product\Category;
  8 +use App\Models\Product\Product;
  9 +use App\Models\Project\OnlineCheck;
  10 +use App\Models\Project\Project;
  11 +use App\Models\Project\WebTrafficConfig;
  12 +use App\Models\Visit\SyncSubmitTask;
  13 +use App\Models\Visit\Visit;
  14 +use App\Models\WebSetting\WebLanguage;
  15 +use App\Services\ProjectServer;
  16 +use Carbon\Carbon;
  17 +use Facade\Ignition\DumpRecorder\Dump;
  18 +use GuzzleHttp\Client;
  19 +use GuzzleHttp\Promise\Utils;
  20 +use Illuminate\Console\Command;
  21 +use Illuminate\Database\Eloquent\Model;
  22 +use Illuminate\Support\Facades\DB;
  23 +use Illuminate\Support\Facades\Log;
  24 +use Illuminate\Support\Facades\Redis;
  25 +use Illuminate\Support\Str;
  26 +
  27 +/**
  28 + * 网站引流 修复
  29 + * Class Traffic
  30 + * @package App\Console\Commands
  31 + * @author zbj
  32 + * @date 2023/5/18
  33 + */
  34 +class WebTrafficFix extends Command
  35 +{
  36 +
  37 + /**
  38 + * The name and signature of the console command.
  39 + *
  40 + * @var string
  41 + */
  42 + protected $signature = 'web_traffic_fix {type} {date} {need_num}'; // 1 2024-05-16 44
  43 +
  44 + /**
  45 + * The console command description.
  46 + *
  47 + * @var string
  48 + */
  49 + protected $description = '网站引流';
  50 +
  51 + /**
  52 + * Create a new command instance.
  53 + *
  54 + * @return void
  55 + */
  56 + public function __construct()
  57 + {
  58 + parent::__construct();
  59 + }
  60 +
  61 + /**
  62 + * google域名后缀
  63 + * @var string[]
  64 + */
  65 + protected $suffix = [
  66 + 'co.jp' => '日本',
  67 + 'com.tr' => '土耳其',
  68 + 'nl' => '荷兰',
  69 + 'ru' => '俄罗斯',
  70 + 'fr' => '法国',
  71 + 'co.kr' => '韩国',
  72 + 'fi' => '芬兰',
  73 + 'be' => '比利时',
  74 + 'lt' => '立陶宛',
  75 + 'es' => '西班牙',
  76 + 'it' => '意大利',
  77 + 'com.au' => '澳大利亚',
  78 + 'no' => '挪威',
  79 + 'al' => '阿尔巴尼亚',
  80 + 'pt' => '葡萄牙',
  81 + 'lv' => '拉脱维亚',
  82 + 'hu' => '匈牙利',
  83 + 'cz' => '捷克',
  84 + 'de' => '德国',
  85 + 'ca' => '加拿大',
  86 + 'co.in' => '印度',
  87 + 'co.uk' => '英国',
  88 + 'com.vn' => '越南',
  89 + 'com.br' => '巴西',
  90 + 'co.il' => '以色列',
  91 + 'pl' => '波兰',
  92 + 'com.eg' => '埃及',
  93 + 'co.th' => '泰国',
  94 + 'sk' => '斯洛伐克',
  95 + 'ro' => '罗马尼亚',
  96 + 'com.mx' => '墨西哥',
  97 + 'com.my' => '马来西亚',
  98 + 'com.pk' => '巴基斯坦',
  99 + 'co.nz' => '新西兰',
  100 + 'co.za' => '南非',
  101 + 'com.ar' => '阿根廷',
  102 + 'com.kw' => '科威特',
  103 + 'com.sg' => '新加坡',
  104 + 'com.co' => '哥伦比亚',
  105 + 'co.id' => '印度尼西亚',
  106 + 'gr' => '希腊',
  107 + 'bg' => '保加利亚',
  108 + 'mn' => '蒙古',
  109 + 'dk' => '丹麦',
  110 + 'com.sa' => '沙特阿拉伯',
  111 + 'com.pe' => '秘鲁',
  112 + 'com.ph' => '菲律宾',
  113 + 'com.ua' => '乌克兰',
  114 + 'ge' => '格鲁吉亚',
  115 + 'ae' => '阿拉伯联合酋长国',
  116 + 'tn' => '突尼斯',
  117 + ];
  118 +
  119 + /**
  120 + * 概率值
  121 + * @var int[]
  122 + */
  123 + protected $sjjg = [720, 280];//访问间隔占比 访问|不访问
  124 + //访问页面类型占比 产品详情页、单页|产品分类页
  125 + protected $ymzb = [
  126 + 'urls_cats' => 700,
  127 + 'urls_details' => 300
  128 + ];
  129 + protected $sdzb = [600, 200, 150, 50]; //访问页面深度占比 1页|2页|3-6页|7-11页
  130 + protected $yddzb = [1 => 700, 2 => 300]; //移动端占比 pc|mobile
  131 + //模拟访问来源占比 (美国)
  132 + protected $lyzb = [
  133 + 'https://www.google.com/' => 630,
  134 + 'http://www.google.com/' => 30,
  135 + 'http://www.bing.com/' => 20,
  136 + 'https://www.bing.com/' => 5,
  137 + 'https://www.youtube.com/' => 5,
  138 + 'https://search.yahoo.com/' => 5,
  139 + 'https://www.facebook.com/' => 5,
  140 + ];
  141 +
  142 + //俄语
  143 + protected $eylyzb = [
  144 + 'https://www.yandex.com/' => 630,
  145 + 'https://www.google.com/' => 30,
  146 + 'http://www.google.com/' => 30,
  147 + 'http://www.bing.com/' => 20,
  148 + 'https://www.bing.com/' => 5,
  149 + 'https://www.youtube.com/' => 5,
  150 + 'https://search.yahoo.com/' => 5,
  151 + 'https://www.facebook.com/' => 5,
  152 + ];
  153 +
  154 + protected $otherzb = [700, 300]; //模拟访问来源占比 (非美国) google.com|google.其他后缀
  155 +
  156 + protected $pc_ua = [
  157 + 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',
  158 + 1 => 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
  159 + 2 => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1'
  160 + ];
  161 +
  162 + protected $mobile_ua = [
  163 + 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',
  164 + ];
  165 +
  166 + /**
  167 + * @return bool
  168 + */
  169 + public function handle()
  170 + {
  171 + try {
  172 + $type = $this->argument('type');
  173 + $date = $this->argument('date');
  174 + $need_num = $this->argument('need_num');
  175 +
  176 + // $project_list = $this->getProjectList($type);
  177 + // exit;
  178 + while (true) {
  179 +
  180 +
  181 + $project = Redis::rpop('web_traffic_fix');
  182 + if(empty($project)){
  183 +
  184 + break;
  185 + }
  186 + $project_list = [json_decode($project, true)];
  187 + foreach ($project_list as $project) {
  188 + ProjectServer::useProject($project['project_id']);
  189 + // if($project['project_id'] <= 135){
  190 + // continue;
  191 + // }
  192 + echo 'project_id:' . $project['project_id'] . PHP_EOL;
  193 + Log::info('web_traffic_fix project_id:' . $project['project_id']);
  194 + $ip_num = DB::connection('custom_mysql')->table('gl_customer_visit')->where('updated_date', $date)->count();
  195 + if ($ip_num >= 30) {
  196 + echo $ip_num . PHP_EOL;
  197 + continue;
  198 + }
  199 +
  200 + $randomTime = [];
  201 + for ($i = 0; $i < $need_num - $ip_num; $i++) {
  202 + $randomTime[] = Carbon::make($date)->addSeconds(rand(0, 86400))->toDateTimeString();
  203 + }
  204 + sort($randomTime);
  205 + echo 'count:' . count($randomTime) . PHP_EOL;
  206 + $project_urls = $this->getProductUrls($project['project_id']);
  207 + $project_urls['home'] = $project['domain'];
  208 +
  209 + $data = [];
  210 + foreach ($randomTime as $time) {
  211 + //随机引流间隔
  212 + $res_sjjg = $this->get_rand($this->sjjg);
  213 + if ($res_sjjg == 1) {
  214 + continue;
  215 + }
  216 +
  217 + //随机访问页面
  218 + $project['visit_urls'] = $this->getVisitUrls($project_urls);
  219 + //随机客户端
  220 + $project['device_port'] = $this->get_rand($this->yddzb);
  221 + $project['user_agent'] = $project['device_port'] == 1 ? Arr::random($this->pc_ua) : Arr::random($this->mobile_ua);
  222 + $a = time();
  223 + $project['ip'] = $this->getIpAreas([$project['project_id']], $time)[0] ?? '';
  224 + foreach ($project['visit_urls'] as $url) {
  225 + $time = Carbon::make($time)->addSeconds(rand(2, 15))->toDateTimeString();
  226 + $url_array = parse_url($project['domain']);
  227 + $referrer_url = $this->getReferer($project['ip']['ip_area'], $project['lang']);
  228 + $array = [
  229 + 'ip' => $project['ip']['ip'],
  230 + 'domain' => $url_array['host'] ?? '',
  231 + 'referer' => $referrer_url,
  232 + 'user_agent' => $project['user_agent'],
  233 + 'data' => [
  234 + 'url' => $url,
  235 + 'domain' => empty($url_array['host']) ? '' : $url_array['scheme'] . '://' . $url_array['host'],
  236 + 'device_port' => in_array($project['device_port'], array_keys(Visit::deviceMap())) ? $project['device_port'] : Visit::DEVICE_PC,
  237 + 'referrer_url' => $referrer_url
  238 + ],
  239 + ];
  240 + $data[] = [
  241 + 'data' => json_encode($array),
  242 + 'type' => SyncSubmitTask::TYPE_VISIT,
  243 + 'created_at' => $time,
  244 + 'updated_at' => $time,
  245 + 'status' => 3,
  246 + 'traffic' => 1,
  247 + 'project_id' => $project['project_id'],
  248 + ];
  249 + }
  250 +
  251 + }
  252 + DB::table('gl_sync_submit_task_20240516')->insert($data);
  253 + }
  254 + }
  255 + Log::info('web_traffic_fix finish');
  256 + }catch (\Exception $e){
  257 + dump($e->getMessage());
  258 + Log::info('web_traffic_fix error:' . $e->getMessage());
  259 + }
  260 + }
  261 +
  262 + /**
  263 + * 非俄语站的引流的项目
  264 + */
  265 + protected function getProjectList($type){
  266 + $ru_lang_id = WebLanguage::getIdByLang('ru');
  267 +
  268 + //推广项目
  269 + $list = Project::with('domainInfo')
  270 + ->leftJoin('gl_project_deploy_optimize as pdo', 'pdo.project_id', '=', 'gl_project.id')
  271 + ->leftJoin('gl_project_online_check as poc', 'poc.project_id', '=', 'gl_project.id')
  272 + ->where('pdo.domain', '>', 0)
  273 + ->where('poc.qa_status', OnlineCheck::STATUS_ONLINE_TRUE)
  274 + ->whereIn('gl_project.type', [Project::TYPE_TWO, Project::TYPE_FOUR])
  275 + ->where('gl_project.is_upgrade', 0) //非升级项目
  276 + ->where('gl_project.main_lang_id', '<>', $ru_lang_id) //非俄语站
  277 + ->where(function ($query) use ($type) {
  278 + if($type == 1){
  279 + //1-3个月项目
  280 + $startTime = Carbon::now()->addMonths(-4)->toDateString();
  281 + $endTime = Carbon::now()->addMonths(-1)->toDateString();
  282 + $query->whereBetween('pdo.start_date', [$startTime,$endTime]);
  283 + }elseif($type == 2){
  284 + //4-8个月项目
  285 + $startTime = Carbon::now()->addMonths(-9)->startOfDay()->toDateTimeString();
  286 + $endTime = Carbon::now()->addMonths(-4)->endOfDay()->toDateTimeString();
  287 + $query->whereBetween('pdo.start_date', [$startTime,$endTime]);
  288 + }else{
  289 + //大于9个月项目
  290 + $startTime = Carbon::now()->addMonths(-9)->startOfDay()->toDateTimeString();
  291 + $query->where('pdo.start_date', '<', $startTime);
  292 + }
  293 + })->select(['pdo.project_id','gl_project.main_lang_id','gl_project.id'])
  294 + ->orderBy('project_id')
  295 + ->get();
  296 + //其他地方在引流的域名
  297 + $other = DB::connection('projects_mysql')->table('projects')->where('switch', 1)->pluck('domain')->toArray();
  298 +
  299 + foreach ($list as $project) {
  300 + $lang = WebLanguage::getLangById($project['main_lang_id']??1)['short'];
  301 + if(empty($project->domainInfo['domain'])){
  302 + continue;
  303 + }
  304 + //其他地方在引流就不再引流了
  305 + if(in_array($project->domainInfo['domain'], $other)){
  306 + continue;
  307 + }
  308 + $data = [
  309 + 'project_id' => $project['project_id'],
  310 + 'domain' => 'https://' . $project->domainInfo['domain'] . '/',
  311 + 'lang' => $lang
  312 + ];
  313 +
  314 + Redis::lpush('web_traffic_fix', json_encode($data));
  315 + }
  316 + return true;
  317 + }
  318 +
  319 + /**
  320 + * 获取产品分类、单页和详情链接
  321 + */
  322 + protected function getProductUrls($project_id){
  323 + //已发布产品分类页面
  324 + $data['urls_cats'] = DB::connection('custom_mysql')->table('gl_product_category')
  325 + ->where('project_id', $project_id)->where('status', Category::STATUS_ACTIVE)
  326 + ->whereNull('deleted_at')
  327 + ->pluck('route','id')->toArray();
  328 +
  329 + //已发布单页面
  330 + $data['urls_page'] = [];
  331 +// $data['urls_page'] = DB::connection('custom_mysql')->table('gl_web_custom_template')
  332 +// ->where('project_id', $project_id)->where('url', '<>', '404')->where('status', BCustomTemplate::STATUS_ACTIVE)->pluck('url', 'id')->toArray();
  333 +
  334 + //已发布产品详情页
  335 + $data['urls_details'] = DB::connection('custom_mysql')->table('gl_product')
  336 + ->where('project_id', $project_id)->where('status', Product::STATUS_ON)
  337 + ->whereNull('deleted_at')
  338 + ->pluck('route', 'id')->toArray();
  339 +
  340 + $data['urls_cats'] = array_merge($data['urls_cats'], $data['urls_page']);
  341 + if(empty($data['urls_cats'])){
  342 + $data['urls_cats'] = $data['urls_details'];
  343 + }
  344 + DB::disconnect('custom_mysql');
  345 + return $data;
  346 + }
  347 +
  348 + /**
  349 + * 获取地区IP
  350 + */
  351 + protected function getIpAreas($project_ids, $time)
  352 + {
  353 + //本地时间为7-23点的地区
  354 + $h = date('H', strtotime($time));
  355 + $areas = [];
  356 + $list = DB::table('gl_area_timezone')->get();
  357 + $time_zones = [];
  358 + foreach ($list as $v) {
  359 + $v = (array)$v;
  360 + $country_hour = $h + $v['diff'];
  361 + if ($country_hour < 0) {
  362 + $country_hour = 24 + $country_hour;
  363 + }
  364 + if ($country_hour >= 7 && $country_hour < 23) {
  365 + $areas[] = $v['name'];
  366 + $time_zones[$v['name']] = $v['diff'];
  367 + }
  368 + }
  369 + $data = [];
  370 + foreach ($project_ids as $project_id){
  371 + //引流配置
  372 + $config = WebTrafficConfig::getCacheInfoByProjectId($project_id);
  373 + $main_countries = !empty($config->main_countries) ? explode(',',$config->main_countries) : [];
  374 + $filter_countries = !empty($config->filter_countries) ? explode(',',$config->filter_countries) : [];
  375 +
  376 + if($main_countries){
  377 + $areas = $main_countries;
  378 + }
  379 +
  380 + if($filter_countries){
  381 + $areas2 = [];
  382 + foreach ($areas as $v){
  383 + if(!in_array($v, $filter_countries)){
  384 + $areas2[] = $v;
  385 + }
  386 + }
  387 + $areas = $areas2;
  388 + }
  389 +
  390 + //根据地区随机取该地区的IP
  391 + $ipdata = DB::table('gl_xunpan_ipdata')->whereIn('ip_area', $areas)->inRandomOrder()->first();
  392 + if(!$ipdata){
  393 + continue;
  394 + }
  395 +
  396 + $ipdata = (array)$ipdata ?: [];
  397 + $ipdata['diff'] = $time_zones[$ipdata['ip_area']];
  398 + $data[] = $ipdata;
  399 + }
  400 + return $data;
  401 + }
  402 +
  403 + /**
  404 + * 概率算法
  405 + */
  406 + protected function get_rand($proArr) {
  407 + $result = '';
  408 + $proSum = array_sum($proArr);
  409 + foreach ($proArr as $key => $proCur) {
  410 + $randNum = mt_rand(1, $proSum);
  411 + if ($randNum <= $proCur) {
  412 + $result = $key;
  413 + break;
  414 + } else {
  415 + $proSum -= $proCur;
  416 + }
  417 + }
  418 + unset ($proArr);
  419 + return $result;
  420 + }
  421 +
  422 + /**
  423 + * 根据随机访问深度 随机获取访问页面
  424 + */
  425 + protected function getVisitUrls($project_urls){
  426 + //没有分类页 就只访问首页
  427 + if(!$project_urls['urls_cats']){
  428 + $url[] = $project_urls['home'];
  429 + return $url;
  430 + }
  431 + //随机访问深度
  432 + $res_sdzb = $this->get_rand($this->sdzb);
  433 + //随机访问页面类型
  434 + $res_ymzb = $this->get_rand($this->ymzb);
  435 +
  436 + $all_url = array_merge($project_urls['urls_cats'],$project_urls['urls_details']);
  437 + if(!$all_url){
  438 + $url[] = $project_urls['home'];
  439 + return $url;
  440 + }
  441 +
  442 + $url = [];
  443 + if($res_sdzb == 0){//深度一页
  444 + $url[] = $project_urls[$res_ymzb] ? Arr::random($project_urls[$res_ymzb]) : '';
  445 + }elseif($res_sdzb == 1){//深度两页
  446 + $url[] = $project_urls['home'];
  447 + $url[] = $project_urls[$res_ymzb] ? Arr::random($project_urls[$res_ymzb]) : '';
  448 + }elseif($res_sdzb == 2){//深度3-6页
  449 + $yms = rand(2,5); //随机页面数
  450 + $url = Arr::random($all_url, $yms);
  451 + $url = Arr::prepend($url, $project_urls['home']);//首页加到最前面去
  452 + }elseif($res_sdzb == 3){//深度7-11页
  453 + $yms = rand(6,10); //随机页面数
  454 + $url = Arr::random($all_url, $yms);
  455 + $url = Arr::prepend($url, $project_urls['home']);//首页加到最前面去
  456 + }
  457 + foreach ($url as &$v){
  458 + if(!Str::contains($v, $project_urls['home'])){
  459 + if (FALSE === strpos($v, '.htm')) {
  460 + $v .= '/';
  461 + }
  462 + $v = $project_urls['home'] . $v;
  463 + }
  464 + }
  465 +
  466 + Log::channel('traffic')->info('project_id:访问深度' . $res_sdzb, $url);
  467 +
  468 + return array_unique(array_filter($url));
  469 + }
  470 +
  471 + /**
  472 + * 获取访问来路
  473 + */
  474 + protected function getReferer($ip_area, $lang){
  475 +
  476 + if($lang == 'ru'){
  477 + return $this->get_rand($this->eylyzb);
  478 + }
  479 +
  480 + if($ip_area == '美国'){
  481 + $referer = $this->get_rand($this->lyzb);
  482 + }else{
  483 + $referer = 'https://www.google.com/';
  484 +
  485 + $suffix = array_search($ip_area, $this->suffix);
  486 + if($suffix){
  487 + $res_qtzb = $this->get_rand($this->otherzb);
  488 + if($res_qtzb == 1){
  489 + $referer = 'https://www.google.'.$suffix.'/';
  490 + }
  491 + }
  492 + }
  493 + return $referer;
  494 + }
  495 +}
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\File; @@ -4,6 +4,7 @@ namespace App\Http\Controllers\File;
4 4
5 use App\Enums\Common\Code; 5 use App\Enums\Common\Code;
6 use App\Helper\Translate; 6 use App\Helper\Translate;
  7 +use App\Jobs\SyncImageFileJob;
7 use App\Models\File\ErrorFile; 8 use App\Models\File\ErrorFile;
8 use App\Models\File\File; 9 use App\Models\File\File;
9 use App\Models\File\Image as ImageModel; 10 use App\Models\File\Image as ImageModel;
@@ -146,13 +147,7 @@ class FileController @@ -146,13 +147,7 @@ class FileController
146 */ 147 */
147 public function synchronizationFile($fileName){ 148 public function synchronizationFile($fileName){
148 //同步到大文件 149 //同步到大文件
149 - $file_path = config('filesystems.disks.cos')['cdn1'].$this->path.'/'.$fileName;  
150 - $cmd = 'curl -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$this->path.'" https://v6-file.globalso.com/upload.php';  
151 - $code = shell_exec($cmd);  
152 - if(200 != (int)$code){  
153 - $errorFileModel = new ErrorFile();  
154 - $errorFileModel->add(['path'=>$this->path.'/'.$fileName]);  
155 - } 150 + SyncImageFileJob::dispatch(['path'=>$this->path,'name'=>$fileName]);
156 return true; 151 return true;
157 } 152 }
158 153
@@ -204,6 +204,7 @@ class ImageController extends Controller @@ -204,6 +204,7 @@ class ImageController extends Controller
204 $this->response('不支持当前格式',Code::SYSTEM_ERROR); 204 $this->response('不支持当前格式',Code::SYSTEM_ERROR);
205 } 205 }
206 $fileName = $this->getOnlyFilename($name,$param['project_id'] ?? 0); 206 $fileName = $this->getOnlyFilename($name,$param['project_id'] ?? 0);
  207 +
207 //上传到cos 208 //上传到cos
208 if($this->upload_location == 0){ 209 if($this->upload_location == 0){
209 $cosService = new CosService(); 210 $cosService = new CosService();
@@ -265,13 +266,6 @@ class ImageController extends Controller @@ -265,13 +266,6 @@ class ImageController extends Controller
265 */ 266 */
266 public function synchronizationImage($fileName){ 267 public function synchronizationImage($fileName){
267 SyncImageFileJob::dispatch(['path'=>$this->path,'name'=>$fileName]); 268 SyncImageFileJob::dispatch(['path'=>$this->path,'name'=>$fileName]);
268 -// $file_path = getImageUrl($this->path.'/'.$fileName,$this->cache['storage_type'] ?? 0);  
269 -// $cmd = 'curl -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$this->path.'" https://v6-file.globalso.com/upload.php';  
270 -// $code = shell_exec($cmd);  
271 -// if(200 != (int)$code){  
272 -// $errorFileModel = new ErrorFile();  
273 -// $errorFileModel->add(['path'=>$this->path.'/'.$fileName]);  
274 -// }  
275 return true; 269 return true;
276 } 270 }
277 271
@@ -11,6 +11,7 @@ namespace App\Http\Logic\Bside\Setting; @@ -11,6 +11,7 @@ namespace App\Http\Logic\Bside\Setting;
11 11
12 use App\Http\Logic\Bside\BaseLogic; 12 use App\Http\Logic\Bside\BaseLogic;
13 use App\Models\Com\UpdateLog; 13 use App\Models\Com\UpdateLog;
  14 +use App\Models\RouteMap\RouteMap;
14 use App\Models\User\UserLog; 15 use App\Models\User\UserLog;
15 use App\Models\WebSetting\Translate as TranslateModel; 16 use App\Models\WebSetting\Translate as TranslateModel;
16 use App\Models\WebSetting\WebLanguage; 17 use App\Models\WebSetting\WebLanguage;
@@ -284,6 +285,37 @@ class TranslateLogic extends BaseLogic @@ -284,6 +285,37 @@ class TranslateLogic extends BaseLogic
284 } 285 }
285 286
286 /** 287 /**
  288 + * @remark :根据路由获取source+source_id
  289 + * @name :getRouteSource
  290 + * @author :lyh
  291 + * @method :post
  292 + * @time :2024/5/17 15:11
  293 + */
  294 + public function getRouteSource($route){
  295 + $data = ['source'=>0,'source_id'=>0,'is_list'=>0,'is_custom'=>0];
  296 + if(strtolower($route) == 'all'){
  297 + return $this->success($data);
  298 + }
  299 + if($route == '/'){
  300 + $data['source'] = 1;
  301 + return $this->success($data);
  302 + }
  303 + $route = basename($route);
  304 + $routeModel = new RouteMap();
  305 + $routeInfo = $routeModel->read(['route'=>$route]);
  306 + if($routeInfo['source'] == RouteMap::SOURCE_PAGE){
  307 + if($routeInfo['source_id']){
  308 + $data = ['source'=>9,'source_id'=>$routeInfo['source_id'],'is_list'=>0,'is_custom'=>0];
  309 + }
  310 + }
  311 + if($routeInfo['source'] == RouteMap::SOURCE_PAGE){
  312 + if($routeInfo['source_id']){
  313 + $data = ['source'=>9,'source_id'=>$routeInfo['source_id'],'is_list'=>0,'is_custom'=>0];
  314 + }
  315 + }
  316 + }
  317 +
  318 + /**
287 * @remark :处理路由 319 * @remark :处理路由
288 * @name :handleRoute 320 * @name :handleRoute
289 * @author :lyh 321 * @author :lyh
  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 SyncSubmitTaskZbj 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_20240516';
  27 +
  28 + protected $casts = [
  29 + 'data' => 'array',
  30 + ];
  31 +
  32 + /**
  33 + * @param $type
  34 + * @param $data
  35 + * @return bool
  36 + * @author zbj
  37 + * @date 2023/11/28
  38 + */
  39 + public static function addTask($type, $data): bool
  40 + {
  41 + if (empty($data)) {
  42 + return false;
  43 + }
  44 + try {
  45 + $data = [
  46 + 'data' => $data['data'],
  47 + 'domain' => !empty($data['domain']) ? $data['domain'] : request()->getHost(),
  48 + 'ip' => !empty($data['ip']) ? $data['ip'] : request()->getClientIp(),
  49 + 'referer' => !empty($data['referer']) ? $data['referer'] : request()->header('Referer'),
  50 + 'user_agent' => !empty($data['user_agent']) ? $data['user_agent'] : request()->header('user_agent'),
  51 + ];
  52 +
  53 + if(empty($data['referer']) || empty($data['user_agent']) || empty($data['data'])){
  54 + return false;
  55 + }
  56 +
  57 + $model = new self();
  58 + $model->type = $type;
  59 + $model->data = $data;
  60 + !empty($data['submit_time']) && $model->created_at = $data['submit_time'];
  61 + $model->save();
  62 +
  63 + } catch (\Exception $e) {
  64 + Log::error('SyncSubmitTask addTask error', ['msg' => $e->getMessage(), 'data' => $data]);
  65 + return false;
  66 + }
  67 + return true;
  68 + }
  69 +}
@@ -53,11 +53,14 @@ class Visit extends Base @@ -53,11 +53,14 @@ class Visit extends Base
53 /** 53 /**
54 * 访问写入 54 * 访问写入
55 */ 55 */
56 - public static function saveData($data) 56 + public static function saveData($data, $date)
57 { 57 {
  58 + if(!$date){
  59 + $date = date('Y-m-d');
  60 + }
58 //判断IP当天是否有一条数据 61 //判断IP当天是否有一条数据
59 - $visit = Visit::where("ip",$data['ip'])->where("created_at",">=",Carbon::now()->today()->startOfDay())  
60 - ->where("created_at","<=",Carbon::now()->today()->endOfDay()) 62 + $visit = Visit::where("ip",$data['ip'])->where("created_at",">=",Carbon::make($date)->startOfDay())
  63 + ->where("created_at","<=",Carbon::make($date)->endOfDay())
61 ->first(); 64 ->first();
62 DB::connection('custom_mysql')->beginTransaction(); 65 DB::connection('custom_mysql')->beginTransaction();
63 if (!empty($visit) && $visit->count() >= 1){ 66 if (!empty($visit) && $visit->count() >= 1){
@@ -31,7 +31,7 @@ class SyncSubmitTaskService @@ -31,7 +31,7 @@ class SyncSubmitTaskService
31 * @author zbj 31 * @author zbj
32 * @date 2023/11/28 32 * @date 2023/11/28
33 */ 33 */
34 - public static function handler($task) 34 + public static function handler($task, $date = '')
35 { 35 {
36 $data = $task['data']; 36 $data = $task['data'];
37 $checkIpCountry = self::checkIpCountry($data['domain'], $data['ip'], $task['type']); 37 $checkIpCountry = self::checkIpCountry($data['domain'], $data['ip'], $task['type']);
@@ -53,7 +53,7 @@ class SyncSubmitTaskService @@ -53,7 +53,7 @@ class SyncSubmitTaskService
53 53
54 $action = $task['type']; 54 $action = $task['type'];
55 $handler = new self(); 55 $handler = new self();
56 - return $handler->$action($data); 56 + return $handler->$action($data, $date);
57 } 57 }
58 58
59 59
@@ -85,7 +85,7 @@ class SyncSubmitTaskService @@ -85,7 +85,7 @@ class SyncSubmitTaskService
85 * @author zbj 85 * @author zbj
86 * @date 2023/12/4 86 * @date 2023/12/4
87 */ 87 */
88 - public function inquiry($data) 88 + public function inquiry($data, $date)
89 { 89 {
90 90
91 $this->inquiryFilter($data['project_id'], $data); 91 $this->inquiryFilter($data['project_id'], $data);
@@ -113,7 +113,7 @@ class SyncSubmitTaskService @@ -113,7 +113,7 @@ class SyncSubmitTaskService
113 * @author zbj 113 * @author zbj
114 * @date 2023/12/4 114 * @date 2023/12/4
115 */ 115 */
116 - public function visit($data) 116 + public function visit($data, $date)
117 { 117 {
118 118
119 $visit_data = $data['data']; 119 $visit_data = $data['data'];
@@ -132,7 +132,7 @@ class SyncSubmitTaskService @@ -132,7 +132,7 @@ class SyncSubmitTaskService
132 $visit_data['country'] = $data['country']; 132 $visit_data['country'] = $data['country'];
133 $visit_data['updated_date'] = $data['submit_at']->toDateString(); 133 $visit_data['updated_date'] = $data['submit_at']->toDateString();
134 $visit_data['created_at'] = $data['submit_at']; 134 $visit_data['created_at'] = $data['submit_at'];
135 - Visit::saveData($visit_data); 135 + Visit::saveData($visit_data, $date);
136 136
137 return true; 137 return true;
138 } 138 }