作者 zhl

拆分同步数据脚本

  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: zhl
  5 + * Date: 2025/2/18
  6 + * Time: 17:10
  7 + */
  8 +namespace App\Console\Commands\Inquiry;
  9 +
  10 +use App\Models\Channel\Channel;
  11 +use App\Models\Domain\DomainInfo;
  12 +use App\Models\Inquiry\InquiryProject;
  13 +use App\Models\Inquiry\InquiryProjectRoute;
  14 +use App\Models\Product\Category;
  15 +use App\Models\Product\Product;
  16 +use App\Models\Project\OnlineCheck;
  17 +use App\Models\Project\Project;
  18 +use App\Services\ProjectServer;
  19 +use Illuminate\Console\Command;
  20 +use Illuminate\Support\Facades\DB;
  21 +use Illuminate\Support\Facades\Log;
  22 +use Illuminate\Support\Facades\Redis;
  23 +
  24 +/**
  25 + * Class SyncInquiryProjectRoute
  26 + * @package App\Console\Commands\Inquiry
  27 + */
  28 +class SyncInquiryProjectRoute extends Command
  29 +{
  30 + /**
  31 + * The name and signature of the console command.
  32 + *
  33 + * @var string
  34 + */
  35 + protected $signature = 'sync_inquiry_project_route';
  36 +
  37 + /**
  38 + * The console command description.
  39 + *
  40 + * @var string
  41 + */
  42 + protected $description = '同步询盘信息:项目对应路由,';
  43 +
  44 + /**
  45 + * Create a new command instance.
  46 + *
  47 + * @return void
  48 + */
  49 + public function __construct()
  50 + {
  51 + parent::__construct();
  52 + }
  53 +
  54 + /**
  55 + * 同步优化项目及路由
  56 + * TODO 同步v4 v5 v6项目以及路由, 删除过期项目及路由
  57 + * @return bool
  58 + */
  59 + public function handle()
  60 + {
  61 + while (true) {
  62 + $sync_id = Redis::rpop('sync_inquiry_project_route_task');
  63 + if (empty($sync_id)) {
  64 + sleep(60);
  65 + continue;
  66 + }
  67 +
  68 + $task = InquiryProject::where(['id' => $sync_id])->first();
  69 + if (empty($task))
  70 + continue;
  71 +
  72 + // 同步对应项目路由, 以及删除过期路由
  73 + if ($task->version == InquiryProject::VERSION_SIX){
  74 + $this->syncGloV6Route($task);
  75 + } else {
  76 + $this->syncGloV5Route($task);
  77 + }
  78 +
  79 + }
  80 + return true;
  81 + }
  82 +
  83 + /**
  84 + * 同步v4 v5项目路由
  85 + * @param $task
  86 + * @return bool
  87 + */
  88 + public function syncGloV5Route($task)
  89 + {
  90 + $date = intval(date('Ymd'));
  91 +
  92 + $result = file_get_contents(storage_path('logs/sync_inquiry_project_route/' . $task->id . '.json'));
  93 + $result = json_decode($result, true);
  94 + if (empty($result)) {
  95 + // 未获取到数据 删除当前项目过期路由
  96 + $this->deleteExpire($task->id, $date);
  97 + $this->log('syncGloV5Route 未获取到路由信息:' . $task->id . ', 路由获取地址:' . ($task->is_split && $task->test_url ? $task->test_url : $task->main_url) . 'k_u_api.php');
  98 + return false;
  99 + }
  100 +
  101 + foreach ($result as $key=>$val) {
  102 + try {
  103 + $tmp = explode('|', $val);
  104 + $url_tmp = parse_url($tmp[0]);
  105 + $route = trim($url_tmp['path'], '/');
  106 + $title = str_replace('+', ' ', $tmp[1]);
  107 + if (strlen($title) > 200 || strlen($route) > 200) {
  108 + $this->log('syncGloV5Route 路由或标题过长,无效记录');
  109 + continue;
  110 + }
  111 + InquiryProjectRoute::saveProjectRoute($task->id, $title, $route, $date);
  112 + } catch (\Exception $e) {
  113 + $this->log('syncGloV5Route 解析路径:' . $val . ', 错误信息:' . $e->getMessage());
  114 + echo 'syncGloV5Route 解析路径:' . $val . ', 错误信息:' . $e->getMessage() . PHP_EOL;
  115 + }
  116 + }
  117 +
  118 + // 删除当前项目过期路由
  119 + $this->deleteExpire($task->id, $date);
  120 + return true;
  121 + }
  122 +
  123 + /**
  124 + * 同步v6项目路由
  125 + * @param $task
  126 + * @return bool
  127 + */
  128 + public function syncGloV6Route($task)
  129 + {
  130 + $date = intval(date('Ymd'));
  131 + ProjectServer::useProject($task->primary_id);
  132 + // TODO 产品分类标题、路由, 产品标题、路由, 同步到路由表
  133 + $category = Category::where('status', Category::STATUS_ACTIVE)->get(['title', 'route']);
  134 + foreach ($category as $key=>$val) {
  135 + InquiryProjectRoute::saveProjectRoute($task->id, $val->title, $val->route, $date);
  136 + }
  137 +
  138 + // 产品数量会比较多, 所以使用分页 同步数据
  139 + $id = 0;
  140 + while (true) {
  141 + echo '同步项目路由:' . $id . PHP_EOL;
  142 + $product = Product::where('status', Product::STATUS_ON)->where('id', '>', $id)->orderBy('id', 'asc')->limit(1000)->get(['id', 'title', 'route']);
  143 + if ($product->isEmpty())
  144 + break;
  145 +
  146 + foreach ($product as $key=>$val) {
  147 + $id = $val->id;
  148 + InquiryProjectRoute::saveProjectRoute($task->id, $val->title, $val->route, $date);
  149 + }
  150 + }
  151 +
  152 + DB::disconnect('custom_mysql');
  153 +
  154 + // 删除当前项目过期路由
  155 + $this->deleteExpire($task->id, $date);
  156 +
  157 + return true;
  158 + }
  159 +
  160 + /**
  161 + * 删除过期数据, 非当前更新数据, 都删除, 误删第二天再重新同步更新
  162 + * @param $project_id
  163 + * @param $date
  164 + * @return bool
  165 + */
  166 + public function deleteExpire($project_id, $date)
  167 + {
  168 + $project_route_num = InquiryProjectRoute::where(['project_id' => $project_id])->where('date', '<', $date)->delete();
  169 + $this->log('项目ID:' . $project_id . ', 删除过期路由数量:' . $project_route_num);
  170 + return true;
  171 + }
  172 +
  173 + /**
  174 + * 输出日志到特定的文件内, 这个文件需要定时排除内容
  175 + * @param $message
  176 + * @return bool
  177 + */
  178 + public function log($message)
  179 + {
  180 + $message = date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL;
  181 + file_put_contents(storage_path('logs/zhl/output') . date('Y-m-d') . '.log', $message, FILE_APPEND);
  182 + return true;
  183 + }
  184 +}
@@ -27,6 +27,7 @@ class InquiryProject extends Base @@ -27,6 +27,7 @@ class InquiryProject extends Base
27 27
28 /** 28 /**
29 * 保存项目信息 29 * 保存项目信息
  30 + * @param $date
30 * @param $version 31 * @param $version
31 * @param $primary_id 32 * @param $primary_id
32 * @param $project 33 * @param $project
@@ -36,9 +37,8 @@ class InquiryProject extends Base @@ -36,9 +37,8 @@ class InquiryProject extends Base
36 * @param string $test_domain 37 * @param string $test_domain
37 * @return InquiryProject 38 * @return InquiryProject
38 */ 39 */
39 - public static function saveProject($version, $primary_id, $project, $channel, $domain, $is_split = 0, $test_domain = '') 40 + public static function saveProject($date, $version, $primary_id, $project, $channel, $domain, $is_split = 0, $test_domain = '')
40 { 41 {
41 - $date = date('Ymd');  
42 $log = self::where(compact('version', 'primary_id'))->first(); 42 $log = self::where(compact('version', 'primary_id'))->first();
43 if ($log) { 43 if ($log) {
44 $log->date = $date; 44 $log->date = $date;
@@ -25,11 +25,11 @@ class InquiryProjectRoute extends Base @@ -25,11 +25,11 @@ class InquiryProjectRoute extends Base
25 * @param int $project_id gl_inquiry_project 表ID 25 * @param int $project_id gl_inquiry_project 表ID
26 * @param $title 26 * @param $title
27 * @param $route 27 * @param $route
  28 + * @param $date
28 * @return InquiryProjectRoute 29 * @return InquiryProjectRoute
29 */ 30 */
30 - public static function saveProjectRoute($project_id, $title, $route) 31 + public static function saveProjectRoute($project_id, $title, $route, $date)
31 { 32 {
32 - $date = date('Ymd');  
33 $log = self::where(compact('project_id', 'title'))->first(); 33 $log = self::where(compact('project_id', 'title'))->first();
34 if ($log) { 34 if ($log) {
35 $log->date = $date; 35 $log->date = $date;