作者 刘锟

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

@@ -17,7 +17,6 @@ yarn-error.log @@ -17,7 +17,6 @@ yarn-error.log
17 /.idea 17 /.idea
18 /.vscode 18 /.vscode
19 composer.lock 19 composer.lock
20 -app/Console/Commands/Test/Demo.php  
21 app/Console/Commands/Test/DataRecovery.php 20 app/Console/Commands/Test/DataRecovery.php
22 /public/upload 21 /public/upload
23 /public/runtime 22 /public/runtime
@@ -39,7 +39,7 @@ class AiBlogTask extends Command @@ -39,7 +39,7 @@ class AiBlogTask extends Command
39 $aiBlogTaskModel = new AiBlogTaskModel(); 39 $aiBlogTaskModel = new AiBlogTaskModel();
40 while (true){ 40 while (true){
41 $info = $aiBlogTaskModel->where('status',1)->orderBy('id','asc')->first(); 41 $info = $aiBlogTaskModel->where('status',1)->orderBy('id','asc')->first();
42 - if($info === false){ 42 + if(empty($info)){
43 sleep(30); 43 sleep(30);
44 continue; 44 continue;
45 } 45 }
@@ -52,6 +52,11 @@ class AiBlogTask extends Command @@ -52,6 +52,11 @@ class AiBlogTask extends Command
52 $aiBlogService->key = $aiSettingInfo['key']; 52 $aiBlogService->key = $aiSettingInfo['key'];
53 $aiBlogService->task_id = $info['task_id']; 53 $aiBlogService->task_id = $info['task_id'];
54 $result = $aiBlogService->getDetail(); 54 $result = $aiBlogService->getDetail();
  55 + if(!isset($result['status'])){
  56 + //修改任务状态
  57 + $aiBlogTaskModel->edit(['status'=>3],['id'=>$info['id']]);
  58 + continue;
  59 + }
55 if($result['status'] != 200){ 60 if($result['status'] != 200){
56 sleep(10); 61 sleep(10);
57 continue; 62 continue;
@@ -62,7 +62,7 @@ class InquiryDelay extends Command @@ -62,7 +62,7 @@ class InquiryDelay extends Command
62 * @time :2023/7/13 14:39 62 * @time :2023/7/13 14:39
63 */ 63 */
64 public function inquiryForward($post_data){ 64 public function inquiryForward($post_data){
65 - $url = 'https://form.globalso.com/api/external-interface/add/fa043f9cbec6b38f'; 65 + $url = 'https://www.globalso.site/api/external-interface/add/fa043f9cbec6b38f';
66 $post_data_new = []; 66 $post_data_new = [];
67 $post_data_new['refer'] = $post_data['url']; 67 $post_data_new['refer'] = $post_data['url'];
68 $post_data_new['name'] = $post_data['name']; 68 $post_data_new['name'] = $post_data['name'];
@@ -332,17 +332,7 @@ class RelayInquiry extends Command @@ -332,17 +332,7 @@ class RelayInquiry extends Command
332 try { 332 try {
333 $res = false; 333 $res = false;
334 foreach ($ad_task as $task){ 334 foreach ($ad_task as $task){
335 - //需要多个ip访问的国家 随机2-5次访问,只有一次询盘  
336 - if (in_array($val->country_name, $this->multiple_ip_visit_country)) {  
337 - $times = mt_rand(2, 5); //随机次数  
338 - $inquiry_time = mt_rand(1, $times); //第几次询盘  
339 - $this->output('多次访问模拟:' . $times);  
340 - for ($i = 1; $i <= $times; $i++) {  
341 - $res += $this->relayDetail($task, $val, $inquiry_time == $i);  
342 - }  
343 - }else{  
344 - $res += $this->relayDetail($task, $val);  
345 - } 335 + $res += $this->relayDetail($task, $val);
346 $res += $this->relayShopDetail($task, $val); 336 $res += $this->relayShopDetail($task, $val);
347 $res += $this->relayFobDetail($task, $val); 337 $res += $this->relayFobDetail($task, $val);
348 } 338 }
@@ -405,7 +395,7 @@ class RelayInquiry extends Command @@ -405,7 +395,7 @@ class RelayInquiry extends Command
405 * @param $form 395 * @param $form
406 * @return bool 396 * @return bool
407 */ 397 */
408 - public function relayDetail($task, $form, $is_inquiry = true) 398 + public function relayDetail($task, $form)
409 { 399 {
410 $this->output('获取转发对象'); 400 $this->output('获取转发对象');
411 if(empty($task['target'] )){ 401 if(empty($task['target'] )){
@@ -441,62 +431,76 @@ class RelayInquiry extends Command @@ -441,62 +431,76 @@ class RelayInquiry extends Command
441 } 431 }
442 $this->logChannel()->info('随机域名', array_column($random_data, 'url')); 432 $this->logChannel()->info('随机域名', array_column($random_data, 'url'));
443 foreach ($random_data as $item) { 433 foreach ($random_data as $item) {
444 - //手机号过滤  
445 - $phone = $form->phone;  
446 - $filter_phone = $this->get_rand($this->filter_phone);  
447 - if($filter_phone == 0){  
448 - $phone = trim(str_replace("+", '', $phone));  
449 - }elseif($filter_phone == 1){  
450 - $phone = ''; 434 + $times = 1;
  435 + $inquiry_time = 1;
  436 +
  437 + //需要多个ip访问的国家 随机2-5次访问,只有一次询盘
  438 + if (in_array($form->country_name, $this->multiple_ip_visit_country)) {
  439 + $times = mt_rand(2, 5); //随机次数
  440 + $inquiry_time = mt_rand(1, $times); //第几次询盘
  441 + $this->output('多次访问模拟:' . $times);
451 } 442 }
  443 + for ($i = 1; $i <= $times; $i++) {
  444 + $is_inquiry = $inquiry_time == $i;
  445 + //手机号过滤
  446 + $phone = $form->phone;
  447 + $filter_phone = $this->get_rand($this->filter_phone);
  448 + if($filter_phone == 0){
  449 + $phone = trim(str_replace("+", '', $phone));
  450 + }elseif($filter_phone == 1){
  451 + $phone = '';
  452 + }
452 453
453 - // 推送站点  
454 - $domain = $item['url'];  
455 - $is_v6 = $item['is_v6'];  
456 - $re_website = 'https://' . $domain . '/';  
457 -  
458 - //urls  
459 - list($urls, $lang, $inquiry_product_url) = $this->getUrls($is_v6, $domain, $re_website, $form, $task);  
460 - if(!$urls){  
461 - continue;  
462 - }  
463 -  
464 - //ip  
465 - $ip_data = $this->getIpData($form->country_name);  
466 - $ip = $ip_data->ip;  
467 - $country_name = $ip_data->ip_area;  
468 -  
469 - //message  
470 - list($message, $message_id, $msg_lang) = $this->getMessage($task, $form->message, $domain, $inquiry_product_url);  
471 - $lang = $lang ?: $msg_lang; 454 + // 推送站点
  455 + $domain = $item['url'];
  456 + $is_v6 = $item['is_v6'];
  457 + $re_website = 'https://' . $domain . '/';
472 458
473 - $this->output('获取转发设备信息');  
474 - // 客户端 头信息 来源  
475 - $device_port = $form->email ? '1' : '2'; //1 pc 2移动端  
476 - $user_agent = $form->email ? Arr::random($this->pc_ua) : Arr::random($this->mobile_ua);  
477 - $referrer = $this->getReferer($country_name, $lang);  
478 - $this->output('写入数据'); 459 + //urls
  460 + list($urls, $lang, $inquiry_product_url) = $this->getUrls($is_v6, $domain, $re_website, $form, $task);
  461 + if(!$urls){
  462 + continue;
  463 + }
479 464
480 - $pre = 0;  
481 - $start_time = time();  
482 - $seconds = rand(300, 7200); // 开始时间 从5-2小时后开始  
483 - $exists = ReInquiryDetail::where('re_website', $domain)->where('email', $form->email)->first();  
484 - if($exists){  
485 - $this->output('转发站点邮件已存在');  
486 - continue;  
487 - }  
488 - // 写入推送详情  
489 - $re_detail = ReInquiryDetail::createInquiry($task['id'], $form->id, $domain, $country_name, $ip, $form->full_name, $form->email, $phone, $message, $message_id, $device_port,  
490 - $user_agent, $referrer, $urls, $is_v6, date('Y-m-d H:i:s', $start_time + $seconds));  
491 - foreach ($urls as $k=>$v){  
492 - $pre++;  
493 - $seconds += rand(5,60);  
494 - ReInquiryDetailLog::createInquiryLog($re_detail->id, ReInquiryDetailLog::TYPE_VISIT, $pre, $v, date('Y-m-d H:i:s', $start_time + $seconds));  
495 - // 最后一次访问询盘 加上询盘  
496 - if($is_inquiry && $k+1 >= count($urls)){  
497 - $seconds += rand(30,120); 465 + //ip
  466 + $ip_data = $this->getIpData($form->country_name);
  467 + $ip = $ip_data->ip;
  468 + $country_name = $ip_data->ip_area;
  469 +
  470 + //message
  471 + list($message, $message_id, $msg_lang) = $this->getMessage($task, $form->message, $domain, $inquiry_product_url);
  472 + $lang = $lang ?: $msg_lang;
  473 +
  474 + $this->output('获取转发设备信息');
  475 + // 客户端 头信息 来源
  476 + $device_port = $form->email ? '1' : '2'; //1 pc 2移动端
  477 + $user_agent = $form->email ? Arr::random($this->pc_ua) : Arr::random($this->mobile_ua);
  478 + $referrer = $this->getReferer($country_name, $lang);
  479 + $this->output('写入数据');
  480 +
  481 + $pre = 0;
  482 + $start_time = time();
  483 + $seconds = rand(300, 7200); // 开始时间 从5-2小时后开始
  484 + if($is_inquiry) {
  485 + $exists = ReInquiryDetail::where('re_website', $domain)->where('email', $form->email)->first();
  486 + if ($exists) {
  487 + $this->output('转发站点邮件已存在');
  488 + continue;
  489 + }
  490 + }
  491 + // 写入推送详情
  492 + $re_detail = ReInquiryDetail::createInquiry($task['id'], $form->id, $domain, $country_name, $ip, $form->full_name, $form->email, $phone, $message, $message_id, $device_port,
  493 + $user_agent, $referrer, $urls, $is_v6, date('Y-m-d H:i:s', $start_time + $seconds));
  494 + foreach ($urls as $k=>$v){
498 $pre++; 495 $pre++;
499 - ReInquiryDetailLog::createInquiryLog($re_detail->id, ReInquiryDetailLog::TYPE_INQUIRY, $pre, $v, date('Y-m-d H:i:s', $start_time + $seconds)); 496 + $seconds += rand(5,60);
  497 + ReInquiryDetailLog::createInquiryLog($re_detail->id, ReInquiryDetailLog::TYPE_VISIT, $pre, $v, date('Y-m-d H:i:s', $start_time + $seconds));
  498 + // 最后一次访问询盘 加上询盘
  499 + if($is_inquiry && $k+1 >= count($urls)){
  500 + $seconds += rand(30,120);
  501 + $pre++;
  502 + ReInquiryDetailLog::createInquiryLog($re_detail->id, ReInquiryDetailLog::TYPE_INQUIRY, $pre, $v, date('Y-m-d H:i:s', $start_time + $seconds));
  503 + }
500 } 504 }
501 } 505 }
502 } 506 }
@@ -601,16 +605,20 @@ class RelayInquiry extends Command @@ -601,16 +605,20 @@ class RelayInquiry extends Command
601 $form_message = $message; 605 $form_message = $message;
602 $message_id = 0; 606 $message_id = 0;
603 607
604 - // TODO 当原始询盘内容长度大于15个字符, 直接发送原始内容。 608 + // TODO 当原始询盘内容长度大于15个字符, 60%几率直接发送原始内容。
605 if (strlen($message) >= 15) { 609 if (strlen($message) >= 15) {
606 - //原内容非英语,转为对应语种  
607 - if (is_numeric($form_message)) { //数字会被识别为中文  
608 - $lang = 'en';  
609 - } else {  
610 - $translateSl = Translate::translateSl($form_message);  
611 - $lang = $translateSl['texts']['sl'] ?? 'en'; 610 + $not_use_probability = AiCommand::where('key', 'fb_inquiry_text')->value('not_use_probability');
  611 + $randomNumber = rand(0, 100);
  612 + if($randomNumber < $not_use_probability){
  613 + //原内容非英语,转为对应语种
  614 + if (is_numeric($form_message)) { //数字会被识别为中文
  615 + $lang = 'en';
  616 + } else {
  617 + $translateSl = Translate::translateSl($form_message);
  618 + $lang = $translateSl['texts']['sl'] ?? 'en';
  619 + }
  620 + return [$message, $message_id, $lang??''];
612 } 621 }
613 - return [$message, $message_id, $lang??''];  
614 } 622 }
615 623
616 //开启文案替换 624 //开启文案替换
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: zhl
  5 + * Date: 2025/2/17
  6 + * Time: 11:24
  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 +
  23 +/**
  24 + * Class SyncInquiryProject
  25 + * @package App\Console\Commands\Inquiry
  26 + */
  27 +class SyncInquiryProject extends Command
  28 +{
  29 + /**
  30 + * The name and signature of the console command.
  31 + *
  32 + * @var string
  33 + */
  34 + protected $signature = 'sync_inquiry_project';
  35 +
  36 + /**
  37 + * The console command description.
  38 + *
  39 + * @var string
  40 + */
  41 + protected $description = '同步询盘信息:项目以及对应路由,';
  42 +
  43 + /**
  44 + * Create a new command instance.
  45 + *
  46 + * @return void
  47 + */
  48 + public function __construct()
  49 + {
  50 + parent::__construct();
  51 + }
  52 +
  53 + /**
  54 + * 同步优化项目及路由
  55 + * TODO 同步v4 v5 v6项目以及路由, 删除过期项目及路由
  56 + * @return bool
  57 + */
  58 + public function handle()
  59 + {
  60 + echo '开始同步v5' . PHP_EOL;
  61 + $this->syncGloV5();
  62 + echo '开始同步v6' . PHP_EOL;
  63 + $this->syncGloV6();
  64 + echo '删除过期数据' . PHP_EOL;
  65 + $this->deleteExpire();
  66 + return true;
  67 + }
  68 +
  69 + /**
  70 + * 同步v4 、 v5项目
  71 + * @return bool
  72 + */
  73 + public function syncGloV5()
  74 + {
  75 + $result = http_get('https://www.quanqiusou.cn/extend_api/webs/globalso_v5_tg.php');
  76 + $channel = Channel::pluck('contact_mobile', 'id')->toArray();
  77 + foreach ($result as $key=>$val)
  78 + {
  79 + echo '同步项目:' . $val['postid'] . ' - ' . $val['company'] . PHP_EOL;
  80 + // 记录渠道商, 如果渠道有问题, 记录日志, 跳过当前项目, 处理数据后, 第二天再重新同步
  81 + $channel_flag = false;
  82 + $channel_tmp = [];
  83 + foreach ($val['agent'] as $v) {
  84 + $channel_id = array_search($v, $channel);
  85 + if (empty($channel_id)) {
  86 + $this->log('ERROR 代理商找不到不记录当前项目, 代理商手机号码:' . $v);
  87 + $channel_flag = true;
  88 + break;
  89 + }
  90 + array_push($channel_tmp, $channel_id);
  91 + }
  92 +
  93 + if ($channel_flag || empty($channel_tmp)) {
  94 + $this->log('ERROR 代理商找不到不记录当前项目, 项目ID:' . $val['postid']);
  95 + continue;
  96 + }
  97 +
  98 + // 保存项目 以及路由
  99 + $project = InquiryProject::saveProject($val['v'], $val['postid'], $val['company'], implode(',', $channel_tmp), $val['main_url'], $val['is_split'], $val['test_url']);
  100 + $route_domain = $val['is_split'] && $val['test_url'] ? $val['test_url'] : $val['main_url'];
  101 + $this->syncGloV5Route($project->id, $route_domain);
  102 + }
  103 + return true;
  104 + }
  105 +
  106 + /**
  107 + * 同步v4 v5项目路由
  108 + * @param $project_id
  109 + * @param $route_domain
  110 + * @return bool
  111 + */
  112 + public function syncGloV5Route($project_id, $route_domain)
  113 + {
  114 + try{
  115 + $result = http_get($route_domain . 'k_u_api.php');
  116 + if (empty($result)) {
  117 + $this->log('syncGloV5Route 未获取到路由信息:' . $project_id . ', 路由获取地址:' . $route_domain . 'k_u_api.php');
  118 + return false;
  119 + }
  120 + } catch (\Exception $e) {
  121 + $this->log('syncGloV5Route 未获取到路由信息:' . $project_id . ', 路由获取地址:' . $route_domain . 'k_u_api.php' . ', 错误信息:' . $e->getMessage());
  122 + echo 'syncGloV5Route 未获取到路由信息:' . $project_id . ', 路由获取地址:' . $route_domain . 'k_u_api.php' . ', 错误信息:' . $e->getMessage() . PHP_EOL;
  123 + return false;
  124 + }
  125 +
  126 + foreach ($result as $key=>$val) {
  127 + try {
  128 + $tmp = explode('|', $val);
  129 + $url_tmp = parse_url($tmp[0]);
  130 + $route = trim($url_tmp['path'], '/');
  131 + $title = str_replace('+', ' ', $tmp[1]);
  132 + if (strlen($title) > 200 || strlen($route) > 200) {
  133 + $this->log('syncGloV5Route 路由或标题过长,无效记录');
  134 + continue;
  135 + }
  136 + InquiryProjectRoute::saveProjectRoute($project_id, $title, $route);
  137 + } catch (\Exception $e) {
  138 + $this->log('syncGloV5Route 解析路径:' . $val . ', 错误信息:' . $e->getMessage());
  139 + echo 'syncGloV5Route 解析路径:' . $val . ', 错误信息:' . $e->getMessage() . PHP_EOL;
  140 + }
  141 + }
  142 + return true;
  143 + }
  144 +
  145 + /**
  146 + * 同步v6项目
  147 + * @return bool
  148 + */
  149 + public function syncGloV6()
  150 + {
  151 + // 获取优化中台项目
  152 + $project = Project::leftJoin('gl_project_online_check', 'gl_project.id', '=', 'gl_project_online_check.project_id')
  153 + ->where('gl_project.type', Project::TYPE_TWO)
  154 + ->where('gl_project.extend_type', '!=', 5)
  155 + ->where(function ($query) {
  156 + $query->orwhere('gl_project_online_check.qa_status', OnlineCheck::STATUS_ONLINE_TRUE)
  157 + ->orwhere('gl_project.is_upgrade', Project::IS_UPGRADE_TRUE);
  158 + })
  159 + ->limit(5)
  160 + ->get(['gl_project.id', 'gl_project.title', 'gl_project.level', 'gl_project.channel']);
  161 + // 获取所有项目域名
  162 + $domains = DomainInfo::whereIn('project_id', $project->pluck('id')->toArray())->pluck('domain', 'project_id')->toArray();
  163 + foreach ($project as $key=>$val) {
  164 + echo '同步项目:' . $val->id . ' - ' . $val->title . PHP_EOL;
  165 + // 过滤暂停优化项目, 映射类型2, model没有定义常量
  166 + if (in_array(2, $val->level))
  167 + continue;
  168 + $project = InquiryProject::saveProject(InquiryProject::VERSION_SIX, $val->id, $val->title, $val->channel['channel_id'], $domains[$val->id]);
  169 + $this->syncGloV6Route($project->id, $val->id);
  170 + }
  171 + return true;
  172 + }
  173 +
  174 + /**
  175 + * 同步v6项目路由
  176 + * @param $project_id
  177 + * @param $origin_project_id
  178 + * @return bool
  179 + */
  180 + public function syncGloV6Route($project_id, $origin_project_id)
  181 + {
  182 + ProjectServer::useProject($origin_project_id);
  183 + // TODO 产品分类标题、路由, 产品标题、路由, 同步到路由表
  184 + $category = Category::where('status', Category::STATUS_ACTIVE)->get(['title', 'route']);
  185 + foreach ($category as $key=>$val) {
  186 + InquiryProjectRoute::saveProjectRoute($project_id, $val->title, $val->route);
  187 + }
  188 +
  189 + // 产品数量会比较多, 所以使用分页 同步数据
  190 + $id = 0;
  191 + while (true) {
  192 + echo '同步项目路由:' . $id . PHP_EOL;
  193 + $product = Product::where('status', Product::STATUS_ON)->where('id', '>', $id)->orderBy('id', 'asc')->limit(1000)->get(['id', 'title', 'route']);
  194 + if ($product->isEmpty())
  195 + break;
  196 +
  197 + foreach ($product as $key=>$val) {
  198 + $id = $val->id;
  199 + InquiryProjectRoute::saveProjectRoute($project_id, $val->title, $val->route);
  200 + }
  201 + }
  202 +
  203 + DB::disconnect('custom_mysql');
  204 + return true;
  205 + }
  206 +
  207 + /**
  208 + * 删除过期数据, 非当日更新数据, 都删除, 误删第二天再重新同步更新
  209 + * @return bool
  210 + */
  211 + public function deleteExpire()
  212 + {
  213 + $date = intval(date('Ymd'));
  214 + $project_num = InquiryProject::where('date', '<', $date)->delete();
  215 + $project_route_num = InquiryProjectRoute::where('date', '<', $date)->delete();
  216 + $this->log('删除过期项目数量:' . $project_num . ', 删除过期路由数量:' . $project_route_num);
  217 + return true;
  218 + }
  219 +
  220 + /**
  221 + * 输出日志到特定的文件内, 这个文件需要定时排除内容
  222 + * @param $message
  223 + * @return bool
  224 + */
  225 + public function log($message)
  226 + {
  227 + $message = date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL;
  228 + file_put_contents(storage_path('logs/zhl/output') . date('Y-m-d') . '.log', $message, FILE_APPEND);
  229 + return true;
  230 + }
  231 +}
@@ -243,7 +243,7 @@ class postInquiry extends Command @@ -243,7 +243,7 @@ class postInquiry extends Command
243 'source' => 5, 243 'source' => 5,
244 ]; 244 ];
245 245
246 - $result = Http::withoutVerifying()->timeout(30)->post('https://form.globalso.com/api/external-interface/add/fa043f9cbec6b38f', $data); 246 + $result = Http::withoutVerifying()->timeout(30)->post('https://www.globalso.site/api/external-interface/add/fa043f9cbec6b38f', $data);
247 $res = $result->json(); 247 $res = $result->json();
248 //兼容接口返回格式 248 //兼容接口返回格式
249 if (!empty($res['data'][0]['status'])) { 249 if (!empty($res['data'][0]['status'])) {
@@ -255,7 +255,7 @@ class postInquiry extends Command @@ -255,7 +255,7 @@ class postInquiry extends Command
255 $log->remark = mb_substr($res['message'] ?? '', 0, 200); 255 $log->remark = mb_substr($res['message'] ?? '', 0, 200);
256 $log->save(); 256 $log->save();
257 257
258 - Log::channel('inquiry_relay')->error('inquiry_relay v4|v5 inquiry error', [$result->body(), 'https://form.globalso.com/api/external-interface/add/fa043f9cbec6b38f', $data]); 258 + Log::channel('inquiry_relay')->error('inquiry_relay v4|v5 inquiry error', [$result->body(), 'https://www.globalso.site/api/external-interface/add/fa043f9cbec6b38f', $data]);
259 return false; 259 return false;
260 } 260 }
261 return true; 261 return true;
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :CopyOldProject.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/2/18 14:10
  8 + */
  9 +
  10 +namespace App\Console\Commands\Project;
  11 +
  12 +use App\Services\ProjectServer;
  13 +use Illuminate\Console\Command;
  14 +use Illuminate\Support\Facades\DB;
  15 +use Illuminate\Support\Facades\Log;
  16 +use Illuminate\Support\Facades\Schema;
  17 +
  18 +class CopyOldProject extends Command
  19 +{
  20 + /**
  21 + * The name and signature of the console command.
  22 + *
  23 + * @var string
  24 + */
  25 + protected $signature = 'copy_project_s {old_project_id} {project_id}';
  26 +
  27 + /**
  28 + * The console command description.
  29 + *
  30 + * @var string
  31 + */
  32 + protected $description = 'copy--复制项目';
  33 +
  34 + public function handle()
  35 + {
  36 + $old_project_id = $this->argument('old_project_id');
  37 + $this->output('CopyProjectJob start, old_project_id: ' . $old_project_id);
  38 + $project_id = $this->argument('project_id');
  39 + $this->output('CopyProjectJob start, project_id: ' . $project_id);
  40 + $this->copyMysql($old_project_id,$project_id);
  41 + return true;
  42 + }
  43 +
  44 +
  45 +
  46 + //复制数据库
  47 + public function copyMysql($project_id,$new_project_id){
  48 + //切换数据库配置
  49 + $project = ProjectServer::useProject($new_project_id);
  50 + //创建数据库
  51 + ProjectServer::createDatabase($project);
  52 + //创建表
  53 + $this->initTable($project_id,$new_project_id);
  54 + }
  55 +
  56 + /**
  57 + * @remark :创建数据库
  58 + * @name :initTable
  59 + * @author :lyh
  60 + * @method :post
  61 + * @time :2023/12/11 10:09
  62 + */
  63 + public function initTable($project_id, $news_project_id)
  64 + {
  65 + // 设置源数据库
  66 + config(['database.connections.custom_tmp_mysql_copy.database' => 'gl_data_' . $project_id]);
  67 + $database_name = DB::connection('custom_tmp_mysql_copy')->getDatabaseName();
  68 + // 获取源数据库的所有表
  69 + $tables = Schema::connection('custom_tmp_mysql_copy')->getAllTables();
  70 + $tables = array_column($tables, 'Tables_in_' . $database_name);
  71 + foreach ($tables as $table) {
  72 + // 目标数据库是否存在该表
  73 + $has_table = Schema::connection('custom_mysql')->hasTable($table);
  74 + if ($has_table) {
  75 + // 1. 删除目标数据库中的表
  76 + DB::connection('custom_mysql')->statement("DROP TABLE IF EXISTS {$table}");
  77 + }
  78 + // 2. 重新创建表
  79 + $sql = DB::connection('custom_tmp_mysql_copy')->select("SHOW CREATE TABLE {$table}");
  80 + DB::connection('custom_mysql')->statement(get_object_vars($sql[0])['Create Table']);
  81 + // 3. 跳过指定的表
  82 + if (in_array($table, [
  83 + 'gl_customer_visit',
  84 + 'gl_customer_visit_item',
  85 + 'gl_inquiry_other',
  86 + 'gl_inquiry_form_data',
  87 + 'gl_inquiry_form'
  88 + ])) {
  89 + continue;
  90 + }
  91 + // 4. 重新插入数据
  92 + DB::connection('custom_mysql')->table($table)->insertUsing(
  93 + [], // 插入所有列
  94 + function ($query) use ($table, $project_id) {
  95 + $name = 'gl_data_' . $project_id . '.' . $table;
  96 + $query->select('*')->from("{$name}");
  97 + }
  98 + );
  99 + // 5. 更新 project_id(如果存在)
  100 + if (Schema::connection('custom_mysql')->hasColumn($table, 'project_id')) {
  101 + DB::connection('custom_mysql')->table($table)->update(['project_id' => $news_project_id]);
  102 + }
  103 + }
  104 + return true;
  105 + }
  106 +
  107 + /**
  108 + * @param $message
  109 + * @return bool
  110 + */
  111 + public function output($message)
  112 + {
  113 + $date = date('Y-m-d H:i:s');
  114 + $output = $date . ', ' . $message . PHP_EOL;
  115 + echo $output;
  116 + Log::info($output);
  117 + return true;
  118 + }
  119 +}
@@ -224,29 +224,43 @@ class CopyProject extends Command @@ -224,29 +224,43 @@ class CopyProject extends Command
224 * @method :post 224 * @method :post
225 * @time :2023/12/11 10:09 225 * @time :2023/12/11 10:09
226 */ 226 */
227 - public function initTable($project_id,$news_project_id) 227 + public function initTable($project_id, $news_project_id)
228 { 228 {
229 - config(['database.connections.custom_tmp_mysql_copy.database' => 'gl_data_'.$project_id]); 229 + // 设置源数据库
  230 + config(['database.connections.custom_tmp_mysql_copy.database' => 'gl_data_' . $project_id]);
230 $database_name = DB::connection('custom_tmp_mysql_copy')->getDatabaseName(); 231 $database_name = DB::connection('custom_tmp_mysql_copy')->getDatabaseName();
  232 + // 获取源数据库的所有表
231 $tables = Schema::connection('custom_tmp_mysql_copy')->getAllTables(); 233 $tables = Schema::connection('custom_tmp_mysql_copy')->getAllTables();
232 $tables = array_column($tables, 'Tables_in_' . $database_name); 234 $tables = array_column($tables, 'Tables_in_' . $database_name);
233 foreach ($tables as $table) { 235 foreach ($tables as $table) {
  236 + // 目标数据库是否存在该表
234 $has_table = Schema::connection('custom_mysql')->hasTable($table); 237 $has_table = Schema::connection('custom_mysql')->hasTable($table);
235 - if (!$has_table) {  
236 - $sql = DB::connection('custom_tmp_mysql_copy')->select("SHOW CREATE TABLE {$table}");  
237 - DB::connection('custom_mysql')->statement(get_object_vars($sql[0])['Create Table']); 238 + if ($has_table) {
  239 + // 1. 删除目标数据库中的表
  240 + DB::connection('custom_mysql')->statement("DROP TABLE IF EXISTS {$table}");
238 } 241 }
239 - if($table == 'gl_customer_visit' || $table == 'gl_customer_visit_item' || $table == 'gl_inquiry_other' || $table == 'gl_inquiry_form_data' || $table == 'gl_inquiry_form'){ 242 + // 2. 重新创建表
  243 + $sql = DB::connection('custom_tmp_mysql_copy')->select("SHOW CREATE TABLE {$table}");
  244 + DB::connection('custom_mysql')->statement(get_object_vars($sql[0])['Create Table']);
  245 + // 3. 跳过指定的表
  246 + if (in_array($table, [
  247 + 'gl_customer_visit',
  248 + 'gl_customer_visit_item',
  249 + 'gl_inquiry_other',
  250 + 'gl_inquiry_form_data',
  251 + 'gl_inquiry_form'
  252 + ])) {
240 continue; 253 continue;
241 } 254 }
242 - DB::connection('custom_mysql')->table($table)->truncate(); // 清空目标表数据 255 + // 4. 重新插入数据
243 DB::connection('custom_mysql')->table($table)->insertUsing( 256 DB::connection('custom_mysql')->table($table)->insertUsing(
244 - [], // 列名数组,留空表示插入所有列  
245 - function ($query) use ($table,$project_id) {  
246 - $name = 'gl_data_'.$project_id.'.'.$table; 257 + [], // 插入所有列
  258 + function ($query) use ($table, $project_id) {
  259 + $name = 'gl_data_' . $project_id . '.' . $table;
247 $query->select('*')->from("{$name}"); 260 $query->select('*')->from("{$name}");
248 } 261 }
249 ); 262 );
  263 + // 5. 更新 project_id(如果存在)
250 if (Schema::connection('custom_mysql')->hasColumn($table, 'project_id')) { 264 if (Schema::connection('custom_mysql')->hasColumn($table, 'project_id')) {
251 DB::connection('custom_mysql')->table($table)->update(['project_id' => $news_project_id]); 265 DB::connection('custom_mysql')->table($table)->update(['project_id' => $news_project_id]);
252 } 266 }
@@ -9,9 +9,13 @@ @@ -9,9 +9,13 @@
9 9
10 namespace App\Console\Commands\Project; 10 namespace App\Console\Commands\Project;
11 11
  12 +use App\Helper\Common;
12 use App\Models\Domain\DomainInfo; 13 use App\Models\Domain\DomainInfo;
13 -use App\Models\Project\Project;  
14 -use App\Models\WebSetting\WebSettingSeo; 14 +use App\Models\Product\Category;
  15 +use App\Models\Product\CategoryRelated;
  16 +use App\Models\Product\Detail;
  17 +use App\Models\Product\Product;
  18 +use App\Models\RouteMap\RouteMap;
15 use App\Services\ProjectServer; 19 use App\Services\ProjectServer;
16 use Illuminate\Console\Command; 20 use Illuminate\Console\Command;
17 use Illuminate\Support\Facades\DB; 21 use Illuminate\Support\Facades\DB;
@@ -25,7 +29,7 @@ class DownloadProject extends Command @@ -25,7 +29,7 @@ class DownloadProject extends Command
25 * 29 *
26 * @var string 30 * @var string
27 */ 31 */
28 - protected $signature = 'downloads_project'; 32 + protected $signature = 'downloads_products';
29 33
30 /** 34 /**
31 * The console command description. 35 * The console command description.
@@ -34,65 +38,95 @@ class DownloadProject extends Command @@ -34,65 +38,95 @@ class DownloadProject extends Command
34 */ 38 */
35 protected $description = '导出项目数据'; 39 protected $description = '导出项目数据';
36 40
37 -// public function handle(){  
38 -// $projectModel = new Project();  
39 -// $data = $projectModel->formatQuery(['channel'=>['like','%"channel_id": "57"%'],'delete_status'=>0])->with(['deploy_optimize'])->get()->toArray();  
40 -// if(!empty($data)){  
41 -// $result = $this->exportData($data);  
42 -// }  
43 -// echo date('Y-m-d H:i:s') . ' ' . json_encode($result) . PHP_EOL;  
44 -// return $result;  
45 -//  
46 -// }  
47 -  
48 public function handle(){ 41 public function handle(){
49 - $data = [];  
50 - $projectModel = new Project();  
51 - $projectList = $projectModel->formatQuery(['delete_status'=>0,'type'=>['in',[2,3]]])->with(['deploy_optimize'])->select(['id','status','type','title','remain_day'])->get()->toArray();;  
52 - foreach ($projectList as $v){  
53 - ProjectServer::useProject($v['id']);  
54 - $seoModel = new WebSettingSeo();  
55 - $seoInfo = $seoModel->read(['project_id'=>$v['id']]);  
56 - if($seoInfo === false){  
57 - $data[] = $v;  
58 - }else{  
59 - if(empty($seoInfo['single_page_suffix'])){  
60 - $data[] = $v; 42 + ProjectServer::useProject(1225);
  43 + $data = $this->downloadProduct();
  44 + DB::disconnect('custom_mysql');
  45 + echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
  46 + return $this->exportData($data);
  47 + }
  48 +
  49 + public function downloadProduct()
  50 + {
  51 + $product = new Product();
  52 + $filed = ['id', 'project_id', 'title' ,'thumb' , 'route' ,'intro','content',
  53 + 'category_id', 'status'];
  54 + $this->order = 'sort';
  55 + $lists = $product->list(['status'=>1],'id',$filed);
  56 + if(!empty($lists)){
  57 + $cate_data = $this->getCategoryList();//分类
  58 + foreach ($lists as $k => $v){
  59 + $v['url'] = 'https://www.autsikinta.com/' . getRouteMap(RouteMap::SOURCE_PRODUCT,$v['id']);
  60 + $v['category_id_text'] = $this->categoryName($v['id'],$cate_data);
  61 + //ToDo::处理图片及文件
  62 + if(!empty($v['thumb']) && !empty($v['thumb']['url'])){
  63 + $v['images'] = getImageUrl($v['thumb']['url']);
  64 + }else{
  65 + $v['images'] = '';
61 } 66 }
  67 + $lists[$k] = $v;
62 } 68 }
63 - DB::disconnect('custom_mysql');  
64 } 69 }
65 - return $this->exportData($data); 70 + echo date('Y-m-d H:i:s') . '数据详情$v:'. json_encode($lists) . PHP_EOL;
  71 + return $lists;
  72 + }
  73 + public function categoryName($product_id,$data){
  74 + $cateRelatedModel = new CategoryRelated();
  75 + $category_id = $cateRelatedModel->where('product_id',$product_id)->pluck('cate_id')->toArray();
  76 + $category_name = '';
  77 + if(!empty($category_id) && !empty($data)){
  78 + foreach ($category_id as $v){
  79 + if(isset($data[$v])){
  80 + $category_name .= $data[$v].',';
  81 + }
  82 + }
  83 + $category_name = trim($category_name,',');
  84 + }
  85 + return $category_name;
  86 + }
  87 + /**
  88 + * @remark :获取所有分类
  89 + * @name :getCategoryList
  90 + * @author :lyh
  91 + * @method :post
  92 + * @time :2023/9/14 13:56
  93 + */
  94 + public function getCategoryList(){
  95 + $data = Common::get_user_cache('product_category',1225);
  96 + if(empty($data)){
  97 + $categoryModel = new Category();
  98 + $data = [];
  99 + $cateList = $categoryModel->list(['project_id'=>1225],['id','title']);
  100 + if(!empty($cateList)){
  101 + foreach ($cateList as $value){
  102 + $data[$value['id']] = $value['title'];
  103 + }
  104 + }
  105 + Common::set_user_cache($data,'product_category',1225);
  106 + }
  107 + return $data;
66 } 108 }
67 -  
68 public function exportData($data){ 109 public function exportData($data){
69 // 创建一个新的 Excel 电子表格实例 110 // 创建一个新的 Excel 电子表格实例
70 $spreadsheet = new Spreadsheet(); 111 $spreadsheet = new Spreadsheet();
71 $sheet = $spreadsheet->getActiveSheet(); 112 $sheet = $spreadsheet->getActiveSheet();
72 // 添加表头 113 // 添加表头
73 - $sheet->setCellValue('A1', '项目ID');  
74 - $sheet->setCellValue('B1', '项目名称');  
75 - $sheet->setCellValue('C1', '域名');  
76 - $sheet->setCellValue('D1', '状态');  
77 - $sheet->setCellValue('E1', '剩余服务时间'); 114 + $sheet->setCellValue('A1', '产品名称');
  115 + $sheet->setCellValue('B1', '产品短描述');
  116 + $sheet->setCellValue('C1', '产品内容');
  117 + $sheet->setCellValue('D1', '产品路由');
  118 + $sheet->setCellValue('E1', '产品分类');
  119 + $sheet->setCellValue('F1', '产品状态');
  120 + $sheet->setCellValue('G1', '产品主图');
78 $rowCount = 2; 121 $rowCount = 2;
79 -// $allData = $this->countAll();  
80 foreach ($data as $v) { 122 foreach ($data as $v) {
81 - $domain = (new DomainInfo())->getDomain($v['deploy_optimize']['domain'] ?? 0);  
82 - if($v['type'] == 1){  
83 - $status = '建站中';  
84 - }elseif ($v['type'] == 2){  
85 - $status = '优化中';  
86 - }elseif ($v['type'] == 3){  
87 - $status = '建站后';  
88 - }else{  
89 - $status = '';  
90 - }  
91 - $sheet->setCellValue('A' . $rowCount, $v['id']);  
92 - $sheet->setCellValue('B' . $rowCount, $v['title']);  
93 - $sheet->setCellValue('C' . $rowCount, $domain);  
94 - $sheet->setCellValue('D' . $rowCount, $status);  
95 - $sheet->setCellValue('E' . $rowCount, $v['remain_day']); 123 + $sheet->setCellValue('A' . $rowCount, $v['title']);
  124 + $sheet->setCellValue('B' . $rowCount, $v['intro']);
  125 + $sheet->setCellValue('C' . $rowCount, $v['content']);
  126 + $sheet->setCellValue('D' . $rowCount, $v['url']);
  127 + $sheet->setCellValue('E' . $rowCount, $v['category_id_text']);
  128 + $sheet->setCellValue('F' . $rowCount, '发布中');
  129 + $sheet->setCellValue('G' . $rowCount, $v['images']);
96 $rowCount++; 130 $rowCount++;
97 } 131 }
98 // 创建一个新的 Excel Writer 对象 132 // 创建一个新的 Excel Writer 对象
@@ -199,17 +199,17 @@ class UpdateSeoTdk extends Command @@ -199,17 +199,17 @@ class UpdateSeoTdk extends Command
199 } 199 }
200 $project_id = $task->project_id; 200 $project_id = $task->project_id;
201 201
202 - echo date('Y-m-d H:i:s') . ' start project_id: ' . $project_id . PHP_EOL; 202 + echo getmypid() . ' ' . date('Y-m-d H:i:s') . ' start project_id: ' . $project_id . PHP_EOL;
203 try { 203 try {
204 $this->project = ProjectServer::useProject($project_id); 204 $this->project = ProjectServer::useProject($project_id);
205 $this->seo_tdk($project_id, $task->id); 205 $this->seo_tdk($project_id, $task->id);
206 DB::disconnect('custom_mysql'); 206 DB::disconnect('custom_mysql');
207 }catch (\Exception $e){ 207 }catch (\Exception $e){
208 - echo date('Y-m-d H:i:s') . 'line: '. $e->getLine() .' error: ' . $project_id . '->' . $e->getMessage() . PHP_EOL; 208 + echo getmypid() . ' ' . date('Y-m-d H:i:s') . 'line: '. $e->getLine() .' error: ' . $project_id . '->' . $e->getMessage() . PHP_EOL;
209 ProjectUpdateTdk::retry($task->id, $e->getMessage()); 209 ProjectUpdateTdk::retry($task->id, $e->getMessage());
210 } 210 }
211 Cache::forget('project_deploy_optimize_info_' . $project_id); 211 Cache::forget('project_deploy_optimize_info_' . $project_id);
212 - echo date('Y-m-d H:i:s') . ' end project_id: ' . $project_id . PHP_EOL; 212 + echo getmypid() . ' ' . date('Y-m-d H:i:s') . ' end project_id: ' . $project_id . PHP_EOL;
213 } 213 }
214 } 214 }
215 public function sendNotify($project_id, $route) 215 public function sendNotify($project_id, $route)
@@ -234,7 +234,7 @@ class UpdateSeoTdk extends Command @@ -234,7 +234,7 @@ class UpdateSeoTdk extends Command
234 'language'=> [], 234 'language'=> [],
235 ]; 235 ];
236 http_post($url, json_encode($param)); 236 http_post($url, json_encode($param));
237 - echo '更新中请稍后, 更新完成将会发送站内信通知更新结果!'. PHP_EOL; 237 + echo getmypid() . ' ' . '更新中请稍后, 更新完成将会发送站内信通知更新结果!'. PHP_EOL;
238 } 238 }
239 public function seo_tdk($project_id, $task_id) 239 public function seo_tdk($project_id, $task_id)
240 { 240 {
@@ -246,7 +246,7 @@ class UpdateSeoTdk extends Command @@ -246,7 +246,7 @@ class UpdateSeoTdk extends Command
246 foreach ($this->maps as $table => $map) { 246 foreach ($this->maps as $table => $map) {
247 $total_page = DB::connection('custom_mysql')->table($table)->count(); 247 $total_page = DB::connection('custom_mysql')->table($table)->count();
248 $update[$table] = ['total_page'=>$total_page, 'title'=>0, 'keyword'=>0, 'des'=>0,'keyword_title'=>0,'keyword_content'=>0]; 248 $update[$table] = ['total_page'=>$total_page, 'title'=>0, 'keyword'=>0, 'des'=>0,'keyword_title'=>0,'keyword_content'=>0];
249 - echo date('Y-m-d H:i:s') . '更新--' . $table . ': 项目id' . $project_id . PHP_EOL; 249 + echo getmypid() . ' ' . date('Y-m-d H:i:s') . '更新--' . $table . ': 项目id' . $project_id . PHP_EOL;
250 $list = DB::connection('custom_mysql')->table($table) 250 $list = DB::connection('custom_mysql')->table($table)
251 ->where(function ($query) use ($table, $map){ 251 ->where(function ($query) use ($table, $map){
252 if($table == 'gl_product'){ 252 if($table == 'gl_product'){
@@ -280,7 +280,7 @@ class UpdateSeoTdk extends Command @@ -280,7 +280,7 @@ class UpdateSeoTdk extends Command
280 } 280 }
281 281
282 282
283 - echo date('Y-m-d H:i:s') . '更新--' . $table . ': 项目id' . $project_id . ':id' . $v['id'] . PHP_EOL; 283 + echo getmypid() . ' ' . date('Y-m-d H:i:s') . '更新--' . $table . ': 项目id' . $project_id . ':id' . $v['id'] . PHP_EOL;
284 $v = DB::connection('custom_mysql')->table($table)->where('id', $v['id'])->first(); 284 $v = DB::connection('custom_mysql')->table($table)->where('id', $v['id'])->first();
285 $v = (array)$v; 285 $v = (array)$v;
286 $data = []; 286 $data = [];
@@ -295,7 +295,7 @@ class UpdateSeoTdk extends Command @@ -295,7 +295,7 @@ class UpdateSeoTdk extends Command
295 } 295 }
296 //已有值的 跳过 296 //已有值的 跳过
297 if ($value) { 297 if ($value) {
298 - echo $field.'已有值 跳过' . PHP_EOL; 298 + echo getmypid() . ' ' . $field.'已有值 跳过' . PHP_EOL;
299 continue; 299 continue;
300 } 300 }
301 301
@@ -335,8 +335,8 @@ class UpdateSeoTdk extends Command @@ -335,8 +335,8 @@ class UpdateSeoTdk extends Command
335 } 335 }
336 else if ($table == 'gl_product_keyword' && $field == 'seo_title') { 336 else if ($table == 'gl_product_keyword' && $field == 'seo_title') {
337 # TODO 聚合页seo title 特殊处理 前缀_1 . 关键词 . 后缀_2 337 # TODO 聚合页seo title 特殊处理 前缀_1 . 关键词 . 后缀_2
338 - $prefix = $this->getPrefixKeyword($project_id, 'prefix', 1);  
339 - $suffix = $this->getPrefixKeyword($project_id, 'suffix', 2); 338 + $prefix = $this->getPrefixKeyword($project_id, 'prefix', 1, $v[$this->topic_fields[$table]]);
  339 + $suffix = $this->getPrefixKeyword($project_id, 'suffix', 2, $v[$this->topic_fields[$table]]);
340 if (empty($prefix) || empty($suffix)) 340 if (empty($prefix) || empty($suffix))
341 continue; 341 continue;
342 $seo_title = $prefix . ' ' . $v[$this->topic_fields[$table]] . ' ' . $suffix; 342 $seo_title = $prefix . ' ' . $v[$this->topic_fields[$table]] . ' ' . $suffix;
@@ -423,7 +423,7 @@ class UpdateSeoTdk extends Command @@ -423,7 +423,7 @@ class UpdateSeoTdk extends Command
423 if(strpos($prompt, '{topic}') !== false){ 423 if(strpos($prompt, '{topic}') !== false){
424 $topic = $data[$this->topic_fields[$table]] ?? ''; 424 $topic = $data[$this->topic_fields[$table]] ?? '';
425 if(!$topic){ 425 if(!$topic){
426 - echo 'topic为空 跳过' . PHP_EOL; 426 + echo getmypid() . ' ' . 'topic为空 跳过' . PHP_EOL;
427 return false; 427 return false;
428 } 428 }
429 $prompt = str_replace('{topic}', $topic, $prompt); 429 $prompt = str_replace('{topic}', $topic, $prompt);
@@ -432,7 +432,7 @@ class UpdateSeoTdk extends Command @@ -432,7 +432,7 @@ class UpdateSeoTdk extends Command
432 if(strpos($prompt, '{keyword}') !== false) { 432 if(strpos($prompt, '{keyword}') !== false) {
433 $keyword = $this->mainKeywords($project_id, 1); 433 $keyword = $this->mainKeywords($project_id, 1);
434 if(!$keyword){ 434 if(!$keyword){
435 - echo '核心关键词为空 跳过' . PHP_EOL; 435 + echo getmypid() . ' ' . '核心关键词为空 跳过' . PHP_EOL;
436 return false; 436 return false;
437 } 437 }
438 $prompt = str_replace('{keyword}', $keyword, $prompt); 438 $prompt = str_replace('{keyword}', $keyword, $prompt);
@@ -441,7 +441,7 @@ class UpdateSeoTdk extends Command @@ -441,7 +441,7 @@ class UpdateSeoTdk extends Command
441 if(strpos($prompt, '{company name}') !== false) { 441 if(strpos($prompt, '{company name}') !== false) {
442 $company_name = $this->companyName($project_id); 442 $company_name = $this->companyName($project_id);
443 if(!$company_name){ 443 if(!$company_name){
444 - echo '公司英文全称为空 跳过' . PHP_EOL; 444 + echo getmypid() . ' ' . '公司英文全称为空 跳过' . PHP_EOL;
445 return false; 445 return false;
446 } 446 }
447 $prompt = str_replace('{company name}', $company_name, $prompt); 447 $prompt = str_replace('{company name}', $company_name, $prompt);
@@ -450,7 +450,7 @@ class UpdateSeoTdk extends Command @@ -450,7 +450,7 @@ class UpdateSeoTdk extends Command
450 if(strpos($prompt, '{company detail}') !== false) { 450 if(strpos($prompt, '{company detail}') !== false) {
451 $company_detail = $this->companyName($project_id, 'company_detail'); 451 $company_detail = $this->companyName($project_id, 'company_detail');
452 if(!$company_detail){ 452 if(!$company_detail){
453 - echo '公司英文描述为空 跳过' . PHP_EOL; 453 + echo getmypid() . ' ' . '公司英文描述为空 跳过' . PHP_EOL;
454 return false; 454 return false;
455 } 455 }
456 $prompt = str_replace('{company detail}', $company_detail, $prompt); 456 $prompt = str_replace('{company detail}', $company_detail, $prompt);
@@ -460,7 +460,7 @@ class UpdateSeoTdk extends Command @@ -460,7 +460,7 @@ class UpdateSeoTdk extends Command
460 foreach ($matches[0] as $key=>$val) { 460 foreach ($matches[0] as $key=>$val) {
461 $keyword = $this->getPrefixKeyword($project_id, 'prefix', $matches[1][$key]); 461 $keyword = $this->getPrefixKeyword($project_id, 'prefix', $matches[1][$key]);
462 if(!$keyword){ 462 if(!$keyword){
463 - echo '前缀关键词为空 跳过' . PHP_EOL; 463 + echo getmypid() . ' ' . '前缀关键词为空 跳过' . PHP_EOL;
464 return false; 464 return false;
465 } 465 }
466 $prompt = str_replace($val, $keyword, $prompt); 466 $prompt = str_replace($val, $keyword, $prompt);
@@ -471,7 +471,7 @@ class UpdateSeoTdk extends Command @@ -471,7 +471,7 @@ class UpdateSeoTdk extends Command
471 foreach ($matches[0] as $key=>$val) { 471 foreach ($matches[0] as $key=>$val) {
472 $keyword = $this->getPrefixKeyword($project_id, 'suffix', $matches[1][$key]); 472 $keyword = $this->getPrefixKeyword($project_id, 'suffix', $matches[1][$key]);
473 if(!$keyword){ 473 if(!$keyword){
474 - echo '前缀关键词为空 跳过' . PHP_EOL; 474 + echo getmypid() . ' ' . '前缀关键词为空 跳过' . PHP_EOL;
475 return false; 475 return false;
476 } 476 }
477 $prompt = str_replace($val, $keyword, $prompt); 477 $prompt = str_replace($val, $keyword, $prompt);
@@ -482,7 +482,7 @@ class UpdateSeoTdk extends Command @@ -482,7 +482,7 @@ class UpdateSeoTdk extends Command
482 if(strpos($prompt, '{core keywords 8}') !== false) { 482 if(strpos($prompt, '{core keywords 8}') !== false) {
483 $main_keyword = $this->mainKeywords($project_id, 8); 483 $main_keyword = $this->mainKeywords($project_id, 8);
484 if(!$main_keyword){ 484 if(!$main_keyword){
485 - echo '核心关键词为空 跳过' . PHP_EOL; 485 + echo getmypid() . ' ' . '核心关键词为空 跳过' . PHP_EOL;
486 return false; 486 return false;
487 } 487 }
488 $prompt = str_replace('{core keywords 8}', $main_keyword, $prompt); 488 $prompt = str_replace('{core keywords 8}', $main_keyword, $prompt);
@@ -499,12 +499,31 @@ class UpdateSeoTdk extends Command @@ -499,12 +499,31 @@ class UpdateSeoTdk extends Command
499 * @param $num 499 * @param $num
500 * @return string 500 * @return string
501 */ 501 */
502 - public function getPrefixKeyword($project_id, $type, $num) 502 + public function getPrefixKeyword($project_id, $type, $num, $topic='')
503 { 503 {
504 $str = ''; 504 $str = '';
505 $info = $this->getDeployOptimize($project_id); 505 $info = $this->getDeployOptimize($project_id);
506 if (!empty($info['keyword_' . $type])) { 506 if (!empty($info['keyword_' . $type])) {
507 $fix_keyword = explode(",", $info['keyword_' . $type]); 507 $fix_keyword = explode(",", $info['keyword_' . $type]);
  508 +
  509 + //去掉标题存在的词
  510 + if ($topic) {
  511 + foreach ($fix_keyword as $k=>$keyword) {
  512 + //处理单词复数 s es ies ves
  513 + $keyword = rtrim($keyword, 'ves');
  514 + $keyword = rtrim($keyword, 'ies');
  515 + $keyword = rtrim($keyword, 'es');
  516 + $keyword = rtrim($keyword, 's');
  517 +
  518 + $topic_words = explode(" ", $topic);
  519 + if($type == 'prefix' && Str::startsWith($topic_words[0], $keyword)){
  520 + unset($fix_keyword[$k]);
  521 + }
  522 + if($type == 'suffix' && Str::startsWith($topic_words[count($topic_words)-1], $keyword)){
  523 + unset($fix_keyword[$k]);
  524 + }
  525 + }
  526 + }
508 //随机取 527 //随机取
509 shuffle($fix_keyword); 528 shuffle($fix_keyword);
510 if (count($fix_keyword) < $num) 529 if (count($fix_keyword) < $num)
@@ -592,6 +611,8 @@ class UpdateSeoTdk extends Command @@ -592,6 +611,8 @@ class UpdateSeoTdk extends Command
592 $text = Gpt::instance()->openai_chat_qqs($prompt); 611 $text = Gpt::instance()->openai_chat_qqs($prompt);
593 612
594 if (!$text) { 613 if (!$text) {
  614 + echo getmypid() . ' ' . '生成失败' . PHP_EOL;
  615 +
595 $cache_key = "ai_error_times_{$project_id}_{$table}_{$id}"; 616 $cache_key = "ai_error_times_{$project_id}_{$table}_{$id}";
596 if (!Cache::get($cache_key)) { 617 if (!Cache::get($cache_key)) {
597 Cache::put($cache_key, 0, 7 * 24 * 3600); 618 Cache::put($cache_key, 0, 7 * 24 * 3600);
1 -<?php  
2 -/**  
3 - * Created by PhpStorm.  
4 - * User: zhl  
5 - * Date: 2023/2/7  
6 - * Time: 17:58  
7 - */  
8 -namespace App\Console\Commands\Test;  
9 -  
10 -  
11 -use App\Helper\Arr;  
12 -use App\Helper\Translate;  
13 -use App\Mail\TextMail;  
14 -use App\Models\Blog\Blog;  
15 -use App\Models\Blog\BlogCategory;  
16 -use App\Models\Com\KeywordVideoTask;  
17 -use App\Models\Com\KeywordVideoTaskLog;  
18 -use App\Models\CustomModule\CustomModuleCategory;  
19 -use App\Models\CustomModule\CustomModuleContent;  
20 -use App\Models\CustomModule\CustomModuleExtentContent;  
21 -use App\Models\Devops\ServerConfig;  
22 -use App\Models\Devops\Servers;  
23 -use App\Models\Devops\ServersIp;  
24 -use App\Models\ExtentModule\ExtensionModuleValue;  
25 -use App\Models\File\File;  
26 -use App\Models\File\File as FileModel;  
27 -use App\Models\File\Image;  
28 -use App\Models\File\Image as ImageModel;  
29 -use App\Models\News\News;  
30 -use App\Models\News\NewsCategory;  
31 -use App\Models\Product\Keyword;  
32 -use App\Models\Product\KeywordRelated;  
33 -use App\Models\Product\Product;  
34 -use App\Models\Project\AutoEmailLog;  
35 -use App\Models\Project\DeployOptimize;  
36 -use App\Models\Project\MinorLanguages;  
37 -use App\Models\Project\Project;  
38 -use App\Models\Purchaser\Purchaser;  
39 -use App\Models\Purchaser\PurchaserInfo;  
40 -use App\Models\RouteMap\RouteMap;  
41 -use App\Models\Template\BCustomTemplate;  
42 -use App\Models\Template\BTemplateCom;  
43 -use App\Models\Template\Setting;  
44 -use App\Models\Template\Template;  
45 -use Illuminate\Console\Command;  
46 -use Illuminate\Support\Facades\Config;  
47 -use Illuminate\Support\Facades\DB;  
48 -use Illuminate\Support\Facades\Mail;  
49 -use Illuminate\Support\Facades\Schema;  
50 -  
51 -  
52 -class Demo extends Command  
53 -{  
54 - /**  
55 - * The name and signature of the console command.  
56 - *  
57 - * @var string  
58 - */  
59 - protected $signature = 'demo';  
60 -  
61 - /**  
62 - * The console command description.  
63 - *  
64 - * @var string  
65 - */  
66 - protected $description = 'demo';  
67 -  
68 - public function handle(){  
69 -// echo date('Y-m-d H:i:s') . 'project_id:' . PHP_EOL;  
70 -// ProjectServer::useProject(3092);  
71 -// $this->delProduct();  
72 -// DB::disconnect('custom_mysql');  
73 -// echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;  
74 - return $this->projectList();  
75 - }  
76 -  
77 - public function toQueue(){  
78 - $info = [  
79 - 'email' => '1123736022@qq.com', // 收件人邮箱  
80 - 'title' => '测试邮件', // 邮件标题  
81 - 'content' => '这是来自163邮箱的测试邮件', // 邮件内容  
82 - ];  
83 - Config::set('mail.mailers.smtp.host', 'smtp.163.com');  
84 - Config::set('mail.mailers.smtp.username', 'lyh103433@163.com');  
85 - Config::set('mail.mailers.smtp.password', 'BMf8B327Nhncunnb');  
86 - Config::set('mail.from.address', 'lyh103433@163.com');  
87 - Config::set('mail.from.name', 'lyh');  
88 - try {  
89 - $status = AutoEmailLog::STATUS_SUCCESS;  
90 - Mail::to([$info['email']])->send(new TextMail(['subject' => $info['title'], 'text' => $info['content']]));  
91 - } catch (\Exception $e) {  
92 - $status = AutoEmailLog::STATUS_ERROR;  
93 - $this->output('任务:' . $info['id'] . ' 邮箱' . $info['email'] . '发送失败,' . $e->getMessage());  
94 - }  
95 - return $status;  
96 - }  
97 - public function projectList(){  
98 - $data = '深圳澄通睿视科技有限公司, 日照源洋包装材料有限公司, 河北途铂机电设备有限责任公司, 宁波市海曙玖鼎纸制品有限公司, 青岛众瑞智能仪器有限公司, 河北新秋国际贸易有限公司, 江西乔森电气有限公司, 沧州艾斯克粉业制造有限公司, 上海希然化工科技有限公司, 石家庄中创进出口有限公司, 东光县恒创利纸箱机械有限公司2021, 天津正能管业有限公司, 河北帷幄纺织有限公司, 广东顺德宝绅源环保科技有限公司, 石家庄艾文尔生物科技有限公司, 浙江福俄电气有限公司, 深圳市嘉盛数据科技有限公司, 江西米德实业有限公司, 苏州稼瑞机械有限公司, 青岛卓亚塑料机械有限公司, 宁波中力螺栓制造有限公司, 中山市万格电器有限公司, 廊坊禹神节水灌溉技术有限公司, 山东索玛特制帽有限公司, 蓝启生物技术(深圳)有限公司, 南宁奥展五金紧固件有限公司, 河北茉悠科技有限公司, 莱科阀门(天津)有限公司, 四川零点自动化系统有限公司, 厦门市戴尔乐新能源汽车有限公司, 宁波爱克利浦电器有限公司, 扬州天定成玩具礼品有限公司, 宁波市金典照明电器有限公司, 杭州法埃姆斯钢构有限公司, 北京迪文科技有限公司, 无锡动为储能科技有限公司, 河北唐蕴生物科技有限公司, 绍兴苏尔黛纺织品有限公司, 河北祈强金属制品有限公司, 上池诊断科技(深圳)有限公司, 泉州市三颖超硬工具有限公司, 宁波杰广电子有限公司, 石家庄德烨管业有限公司, 山东凯特钻具有限公司, 北京思普瑞特科技发展有限公司, 广州市印科标识科技有限公司, 优之科技(深圳)有限公司, 南通赫美特国际贸易有限公司, 天津誉瑞特品科技有限公司, 河北坤焰建材科技有限公司, 绍兴睿博机械有限公司, 西安法斯拓进出口有限公司, 深圳市德诺威电子有限公司, 百润(中国)有限公司, 达时科科技有限责任公司, 陈海英, 四川蓉腾自动化设备有限公司, 石家庄晋吉建材科技有限公司, 石家庄安瑞科气体机械有限公司, 深圳市扬帆纸制品有限公司, 舟山威尔曼机械科技有限公司, 佰纳通科技(北京)有限公司, 宁波嘉佑行科技有限公司, 东莞市凯信脚轮有限公司, 宝鸡轩泰颜料科技有限公司, 东莞市华腾五金制品有限公司, 深圳市思锐宇光电有限公司, 东莞市奥彩数码科技有限公司, 上海垂普国际贸易有限公司, 扬州爱拓户外用品有限公司, 余姚市立鑫电子有限公司, 晋州市金昌盛化工有限公司, 广东阿酷达箱包科技有限公司, 泉州市杰斯特仪器设备有限公司, 三和长兴科技有限公司, 佛山市精一家具有限公司谷腾分公司, 天津市洁雅妇女卫生保健制品有限公司, 江西海瑞天然植物有限公司, 九江贝海玻纤有限公司(客户做新站), 瑞安市齐笙科技有限公司, 石家庄华圣方洲国际贸易有限公司, 深圳市方成教学设备有限公司, 连云港索娜斯贸易有限公司, 睿華電子有限公司, 扬州市极盛照明有限公司, 天津市实丰国际贸易有限责任公司, 厦门亚迅工贸有限公司, 威海旺展旅游用品有限公司, 宁波首安纸业有限公司, 浙江乐马电气有限公司, 广东金莱特智能科技有限公司, 河北科星药业有限公司, 宁波迈可森汽配有限公司, 邯郸市常岚紧固件制造有限公司, 宁波市晶艳贸易有限公司, 苏州荃华生物材料有限公司, 青岛洛城通信息科技有限公司, 合肥领派克机械设备有限公司, 广西绿城工贸有限公司, 一元电气科技有限公司【主站】, 立圣丰(厦门)纺织科技有限公司, 深圳市汉瑞通科技有限公司, 扬州市润芳塑胶包装材料有限公司, 扬州浩邦新能源科技有限公司项目2, 深圳市锦昊安科技有限公司, 四川途乐乐科技有限公司, 天津广大纸业股份有限公司, 西安禾为生物科技有限公司, 西安奥谷生物科技有限公司, 佛山市三水歌谷电器有限公司, 西安麦克斯农用化学有限公司, 瑞安市富锐思进出口有限公司(黑格客户), 北京新科以仁科技发展有限公司, 镇江市惠灵顿膜业有限公司';  
99 - $arr = explode(',',$data);  
100 - $projectModel = new Project();  
101 - $opModel = new DeployOptimize();  
102 - foreach ($arr as $k => $v){  
103 - $v = trim($v);  
104 - $info = $projectModel->read(['title'=>['like','%'.$v.'%']],['id']);  
105 - if($info === false){  
106 - echo date('Y-m-d H:i:s') . '未查询到的项目--'.$v . PHP_EOL;  
107 - }else{  
108 - $opInfo = $opModel->read(['project_id'=>$info['id']]);  
109 - if (strpos($opInfo['special'], '15') !== false) {  
110 - echo date('Y-m-d H:i:s') . '已包含' . PHP_EOL;  
111 - } else {  
112 - if(!empty($opInfo['special'])){  
113 - $special = ','.trim($opInfo['special'],',').',15,';  
114 - }else{  
115 - $special = ',15,';  
116 - }  
117 - $opModel->edit(['special'=>$special],['id'=>$opInfo['id']]);  
118 - echo date('Y-m-d H:i:s') . '未包含AI案例的project_id:'.$opInfo['project_id'] . PHP_EOL;  
119 - }  
120 - }  
121 - }  
122 - echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;  
123 - return true;  
124 - }  
125 -  
126 - /**  
127 - * @remark :删除product  
128 - * @name :delProduct  
129 - * @author :lyh  
130 - * @method :post  
131 - * @time :2025/1/10 9:35  
132 - */  
133 - public function delProduct(){  
134 - $productModel = new Product();  
135 - $list = $productModel->list(['status'=>2]);  
136 - foreach ($list as $k => $v){  
137 - $routeModel = new RouteMap();  
138 - $routeModel->del(['source'=>'product','source_id'=>$v['id']]);  
139 - }  
140 - $productModel->del(['status'=>2]);  
141 - return true;  
142 - }  
143 -  
144 - /**  
145 - * @remark :统计当前模版使用情况  
146 - * @name :countTemplate  
147 - * @author :lyh  
148 - * @method :post  
149 - * @time :2025/1/9 10:59  
150 - */  
151 - public function countTemplate(){  
152 - $bSettingModel = new Setting();  
153 - $lists = $bSettingModel->list();  
154 - $templateModel = new Template();  
155 - foreach ($lists as $v){  
156 - echo date('Y-m-d H:i:s') . '执行的模版id:' .$v['template_id'] . PHP_EOL;  
157 - $templateModel->where(['id'=>$v['template_id']])->increment('number',1);  
158 - }  
159 - return true;  
160 - }  
161 -  
162 - /**  
163 - * @remark :更新产品  
164 - * @name :getProduct  
165 - * @author :lyh  
166 - * @method :post  
167 - * @time :2024/11/27 15:40  
168 - */  
169 - public function getProduct(){  
170 - $productModel = new Product();  
171 - $lists = $productModel->list(['status'=>['!=',3]]);  
172 - if(!empty($lists)){  
173 - foreach ($lists as $v){  
174 - if(!empty($v['keyword_video_id'])){  
175 - foreach ($v['keyword_video_id'] as $val){  
176 - $keywordRelaModel = new KeywordRelated();  
177 - echo date('Y-m-d H:i:s') . 'keyword_id :'.$val . 'product_id :'.$v['id'] . PHP_EOL;  
178 - $keywordRelaModel->edit(['type'=>2],['keyword_id'=>$val,'product_id'=>$v['id']]);  
179 - }  
180 - }  
181 - }  
182 - }  
183 - }  
184 -  
185 - /**  
186 - * @remark :复制表及结构  
187 - * @name :copyProduct  
188 - * @author :lyh  
189 - * @method :post  
190 - * @time :2024/11/27 16:09  
191 - */  
192 - public function copyProduct(){  
193 - $tableName = 'gl_product';  
194 - $copyTableName = 'gl_product_c';  
195 - if (Schema::connection('custom_mysql')->hasTable($copyTableName)) {  
196 - DB::connection('custom_mysql')->statement("DROP TABLE {$copyTableName}");  
197 - }  
198 - // 创建新表并复制数据  
199 - DB::connection('custom_mysql')->statement("CREATE TABLE {$copyTableName} LIKE {$tableName}");  
200 - DB::connection('custom_mysql')->statement("INSERT INTO {$copyTableName} SELECT * FROM {$tableName}");  
201 - }  
202 -  
203 - /**  
204 - * @remark :保存供应商详情  
205 - * @name :savePurchaserInfo  
206 - * @author :lyh  
207 - * @method :post  
208 - * @time :2024/5/29 16:38  
209 - */  
210 - public function savePurchaserInfo(){  
211 - $purchaserModel = new Purchaser();  
212 - $list = $purchaserModel->list();  
213 - foreach ($list as $val){  
214 - $project_id = $val['project_id'];  
215 - $keyword = $val['keyword'];  
216 - $data = json_decode($val['data'],JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);  
217 - $purchaserInfoModel = new PurchaserInfo();  
218 - if(!empty($data)){  
219 - foreach ($data as $k =>$v){  
220 - $v['project_id'] = $project_id;  
221 - $v['keyword'] = $keyword;  
222 - $v['email'] = json_encode($v['email'] ?? [],JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);  
223 - $v['mobile'] = json_encode($v['mobile'] ?? [],JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);  
224 - $v['social_media'] = json_encode($v['social_media'] ?? [],JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);  
225 - $v['image'] = str_replace('admin.hagro.cn','fob.ai.cc',$v['image'] ?? '');  
226 - $param = $v;  
227 - $info = $purchaserInfoModel->read(['keyword'=>$keyword,'buyer_id'=>$v['buyer_id'] ?? '','project_id'=>$project_id],['id']);  
228 -  
229 - if($info === false){  
230 - echo date('Y-m-d H:i:s') . '执行新增 :' . PHP_EOL;  
231 - $purchaserInfoModel->add($param);  
232 - }else{  
233 - echo date('Y-m-d H:i:s') . '数据已存在 :'.$info['id'] . PHP_EOL;  
234 - }  
235 - }  
236 - }  
237 - }  
238 - return true;  
239 - }  
240 -}  
@@ -23,7 +23,10 @@ use App\Models\RouteMap\RouteMap; @@ -23,7 +23,10 @@ use App\Models\RouteMap\RouteMap;
23 use App\Models\Template\BTemplate; 23 use App\Models\Template\BTemplate;
24 use App\Models\Template\Setting; 24 use App\Models\Template\Setting;
25 use App\Services\ProjectServer; 25 use App\Services\ProjectServer;
  26 +use App\Utils\HttpUtils;
  27 +use GuzzleHttp\Exception\GuzzleException;
26 use Illuminate\Console\Command; 28 use Illuminate\Console\Command;
  29 +use Illuminate\Support\Facades\Cache;
27 use Illuminate\Support\Facades\DB; 30 use Illuminate\Support\Facades\DB;
28 use Illuminate\Support\Facades\Schema; 31 use Illuminate\Support\Facades\Schema;
29 32
@@ -58,26 +61,36 @@ class UpdateRoute extends Command @@ -58,26 +61,36 @@ class UpdateRoute extends Command
58 * @time :2023/11/20 15:13 61 * @time :2023/11/20 15:13
59 */ 62 */
60 public function handle(){ 63 public function handle(){
61 - $projectModel = new Project();  
62 - $list = $projectModel->list(['delete_status'=>['=',0],'id'=>2902]);  
63 - foreach ($list as $v){  
64 - echo date('Y-m-d H:i:s') . 'project_id:'.$v['id'] . PHP_EOL;  
65 - ProjectServer::useProject($v['id']);  
66 - $this->getProduct();  
67 - DB::disconnect('custom_mysql');  
68 - }  
69 - echo date('Y-m-d H:i:s') . 'end' . PHP_EOL; 64 +
  65 + $data = $this->ceshi();
  66 +
  67 + echo date('Y-m-d H:i:s') . 'end'.json_encode($data) . PHP_EOL;
70 } 68 }
71 69
72 - public function ceshi($project_id){  
73 - $templateModel = new BTemplate();  
74 - $info = $templateModel->orderBy('id','desc')->first();  
75 - if(!empty($info)){  
76 - $webSettingModel = new Setting();  
77 - $webSettingModel->add(['template_id'=>$info->template_id,'project_id'=>$project_id]); 70 +
  71 + public function ceshi($api_no = null)
  72 + {
  73 + $key = 'extend_projects_list';
  74 + $data = Cache::get($key);
  75 + if (!$data) {
  76 + $api_url = 'http://api.quanqiusou.cn/google-rank/api/extend_projects.php';
  77 + try {
  78 + $data = HttpUtils::get($api_url, []);
  79 + if ($data) {
  80 + $data = Arr::s2a($data);
  81 + Cache::put($key, $data, 4 * 3600);
  82 + }
  83 + } catch (\Exception | GuzzleException $e) {
  84 + errorLog('复制站点项目获取失败', [], $e);
  85 + return false;
  86 + }
  87 + }
  88 + if ($api_no !== null) {
  89 + $data = collect($data)->where('apino', $api_no)->first();
  90 + return $data ?: [];
78 } 91 }
  92 + return $data;
79 } 93 }
80 -  
81 /** 94 /**
82 * @remark :更新产品 95 * @remark :更新产品
83 * @name :updateProduct 96 * @name :updateProduct
@@ -111,11 +124,11 @@ class UpdateRoute extends Command @@ -111,11 +124,11 @@ class UpdateRoute extends Command
111 */ 124 */
112 public function custom_to_blogs(){ 125 public function custom_to_blogs(){
113 $customContentModel = new CustomModuleContent(); 126 $customContentModel = new CustomModuleContent();
114 - $lists = $customContentModel->list(['module_id'=>9]); 127 + $lists = $customContentModel->list(['module_id'=>8]);
115 foreach ($lists as $k => $v){ 128 foreach ($lists as $k => $v){
116 $data = [ 129 $data = [
117 'name'=>$v['name'], 130 'name'=>$v['name'],
118 - 'category_id'=>',1,', 131 + 'category_id'=>',1,2,',
119 'remark'=>$v['remark'], 132 'remark'=>$v['remark'],
120 'text'=>$v['content'], 133 'text'=>$v['content'],
121 'url'=>$v['route'], 134 'url'=>$v['route'],
@@ -123,7 +136,7 @@ class UpdateRoute extends Command @@ -123,7 +136,7 @@ class UpdateRoute extends Command
123 'seo_title'=>$v['seo_title'], 136 'seo_title'=>$v['seo_title'],
124 'seo_description'=>$v['seo_description'], 137 'seo_description'=>$v['seo_description'],
125 'seo_keywords'=>$v['seo_keywords'], 138 'seo_keywords'=>$v['seo_keywords'],
126 - 'project_id'=>1750, 139 + 'project_id'=>1462,
127 'operator_id'=>$v['operator_id'], 140 'operator_id'=>$v['operator_id'],
128 'create_id'=>$v['operator_id'], 141 'create_id'=>$v['operator_id'],
129 'created_at'=>$v['created_at'], 142 'created_at'=>$v['created_at'],
@@ -132,8 +145,8 @@ class UpdateRoute extends Command @@ -132,8 +145,8 @@ class UpdateRoute extends Command
132 ]; 145 ];
133 $blogModel = new Blog(); 146 $blogModel = new Blog();
134 $id = $blogModel->insertGetId($data); 147 $id = $blogModel->insertGetId($data);
135 - RouteMap::setRoute($v['route'], RouteMap::SOURCE_BLOG, $id, 1750);  
136 } 148 }
  149 + return true;
137 } 150 }
138 151
139 public function editProductAlt(){ 152 public function editProductAlt(){
@@ -17,7 +17,7 @@ use GuzzleHttp\Exception\GuzzleException; @@ -17,7 +17,7 @@ use GuzzleHttp\Exception\GuzzleException;
17 class FormGlobalsoApi 17 class FormGlobalsoApi
18 { 18 {
19 //接口地址 19 //接口地址
20 - protected $url = 'https://form.globalso.com'; 20 + protected $url = 'https://www.globalso.site';
21 21
22 /** 22 /**
23 * 设置询盘通知 23 * 设置询盘通知
@@ -179,7 +179,7 @@ class FormGlobalsoApi @@ -179,7 +179,7 @@ class FormGlobalsoApi
179 'num'=>15, 179 'num'=>15,
180 ]; 180 ];
181 $queryString = http_build_query($data); 181 $queryString = http_build_query($data);
182 - $url = "https://form.globalso.com/api/external-interface/domain_con/15243d63ed5a5738?".$queryString; 182 + $url = "https://www.globalso.site/api/external-interface/domain_con/15243d63ed5a5738?".$queryString;
183 try { 183 try {
184 $res = http_get($url,['charset=utf-8']); 184 $res = http_get($url,['charset=utf-8']);
185 } catch (\Exception | GuzzleException $e) { 185 } catch (\Exception | GuzzleException $e) {
@@ -207,7 +207,7 @@ class FormGlobalsoApi @@ -207,7 +207,7 @@ class FormGlobalsoApi
207 'sta_date'=>$month, 207 'sta_date'=>$month,
208 ]; 208 ];
209 $queryString = http_build_query($data); 209 $queryString = http_build_query($data);
210 - $url = 'https://form.globalso.com/api/external-interface/country_con/15243d63ed5a5738?'.$queryString; 210 + $url = 'https://www.globalso.site/api/external-interface/country_con/15243d63ed5a5738?'.$queryString;
211 $res = http_get($url,['charset=utf-8']); 211 $res = http_get($url,['charset=utf-8']);
212 echo date('Y-m-d H:i:s') . '数据:'.json_encode($res) . PHP_EOL; 212 echo date('Y-m-d H:i:s') . '数据:'.json_encode($res) . PHP_EOL;
213 return $res; 213 return $res;
@@ -69,12 +69,23 @@ class Gpt @@ -69,12 +69,23 @@ class Gpt
69 ->withBody(json_encode($data, JSON_UNESCAPED_UNICODE), 'application/json') 69 ->withBody(json_encode($data, JSON_UNESCAPED_UNICODE), 'application/json')
70 ->post($url); 70 ->post($url);
71 $json = $result->json(); 71 $json = $result->json();
  72 +
  73 +// $client = new \GuzzleHttp\Client();
  74 +// $result = $client->request('POST', $url, [
  75 +// 'proxy' => 'http://104.255.171.237:51395', // 代理服务器地址和端口号
  76 +// 'headers' => $this->header,
  77 +// 'json' => $data,
  78 +// 'verify' => false,
  79 +// ])->getBody()->getContents();
  80 +// $json = json_decode($result, true);
  81 +
72 if (!isset($json['text']) || $json['code'] !==200) { 82 if (!isset($json['text']) || $json['code'] !==200) {
73 Log::error('openai_chat_qqs data:', $data); 83 Log::error('openai_chat_qqs data:', $data);
74 Log::error('openai_chat_qqs result:' . (time() - $time), $json === null ? ['null'] : $json); 84 Log::error('openai_chat_qqs result:' . (time() - $time), $json === null ? ['null'] : $json);
75 $json = []; 85 $json = [];
76 } 86 }
77 } catch (\Throwable $e) { 87 } catch (\Throwable $e) {
  88 + Log::error('openai_chat_qqs data:', $data);
78 Log::error('openai_chat_qqs time ' . (time() - $time) . ' error:' . $e->getMessage()); 89 Log::error('openai_chat_qqs time ' . (time() - $time) . ' error:' . $e->getMessage());
79 $json = []; 90 $json = [];
80 } 91 }
@@ -501,7 +501,7 @@ if (!function_exists('getInquiryInformation')) { @@ -501,7 +501,7 @@ if (!function_exists('getInquiryInformation')) {
501 { 501 {
502 $token = md5($domain . date("Y-m-d")); 502 $token = md5($domain . date("Y-m-d"));
503 $source = '1,3'; 503 $source = '1,3';
504 - $url = "https://form.globalso.com/api/external-interface/country_con/15243d63ed5a5738?domain={$domain}&token={$token}&source={$source}&sta_date={$sta_date}"; 504 + $url = "https://www.globalso.site/api/external-interface/country_con/15243d63ed5a5738?domain={$domain}&token={$token}&source={$source}&sta_date={$sta_date}";
505 $client = new Client(['verify' => false]); 505 $client = new Client(['verify' => false]);
506 $http = $client->get($url); 506 $http = $client->get($url);
507 $data = []; 507 $data = [];
@@ -14,6 +14,8 @@ use App\Http\Controllers\Aside\BaseController; @@ -14,6 +14,8 @@ use App\Http\Controllers\Aside\BaseController;
14 use App\Http\Logic\Aside\Devops\ServersLogic; 14 use App\Http\Logic\Aside\Devops\ServersLogic;
15 use App\Models\Devops\Servers as ServersModel; 15 use App\Models\Devops\Servers as ServersModel;
16 use App\Models\Devops\ServersIp; 16 use App\Models\Devops\ServersIp;
  17 +use App\Models\Domain\DomainInfo;
  18 +use App\Models\Project\DeployOptimize;
17 use App\Models\Project\Project; 19 use App\Models\Project\Project;
18 20
19 class ServersController extends BaseController 21 class ServersController extends BaseController
@@ -59,6 +61,22 @@ class ServersController extends BaseController @@ -59,6 +61,22 @@ class ServersController extends BaseController
59 } 61 }
60 unset($this->map['project_name']); 62 unset($this->map['project_name']);
61 } 63 }
  64 + if(isset($this->map['domain']) && !empty($this->map['domain'])){
  65 + $domainModel = new DomainInfo();
  66 + $domainInfo = $domainModel->read(['domain'=>['like','%'.$this->map['domain'].'%']],['id','project_id']);
  67 + if($domainInfo !== false && !empty($domainInfo['project_id'])){
  68 + $projectModel = new Project();
  69 + $projectInfo = $projectModel->read(['id'=>$domainInfo['project_id']],['serve_id']);
  70 + if($projectInfo !== false){
  71 + $serversIpModel = new ServersIp();
  72 + $ipInfo = $serversIpModel->read(['id'=>$projectInfo['serve_id']],['servers_id']);
  73 + if($ipInfo !== false){
  74 + $this->map['id'] = $ipInfo['servers_id'];
  75 + }
  76 + }
  77 + }
  78 + unset($this->map['domain']);
  79 + }
62 $serversModel = new ServersModel(); 80 $serversModel = new ServersModel();
63 $data = $serversModel->lists($this->map,$this->page,$this->row,$this->order); 81 $data = $serversModel->lists($this->map,$this->page,$this->row,$this->order);
64 $this->response('success',Code::SUCCESS,$data); 82 $this->response('success',Code::SUCCESS,$data);
@@ -76,7 +94,6 @@ class ServersController extends BaseController @@ -76,7 +94,6 @@ class ServersController extends BaseController
76 'id'=>'required' 94 'id'=>'required'
77 ],[ 95 ],[
78 'id.required' => '主键不能为空' 96 'id.required' => '主键不能为空'
79 -  
80 ]); 97 ]);
81 $data = $serversLogic->infoServers(); 98 $data = $serversLogic->infoServers();
82 $this->response('success',Code::SUCCESS,$data); 99 $this->response('success',Code::SUCCESS,$data);
@@ -34,10 +34,10 @@ class AiBlogController extends BaseController @@ -34,10 +34,10 @@ class AiBlogController extends BaseController
34 * @time :2025/2/14 13:59 34 * @time :2025/2/14 13:59
35 */ 35 */
36 public function getAiBlog(AiBlog $aiBlog){ 36 public function getAiBlog(AiBlog $aiBlog){
37 - $lists = $aiBlog->lists($this->map,$this->page,$this->row,'id',['id','new_title','task_id','status','created_at','updated_at']); 37 + $lists = $aiBlog->lists($this->map,$this->page,$this->row,'id',['id','new_title','image','task_id','status','created_at','updated_at']);
38 if(!empty($lists) && !empty($lists['list'])){ 38 if(!empty($lists) && !empty($lists['list'])){
39 foreach ($lists['list'] as $k => $v){ 39 foreach ($lists['list'] as $k => $v){
40 - $v['image'] = getImageUrl($v['url'],$this->user['storage_type'],$this->user['project_location']); 40 + $v['image'] = getImageUrl($v['image'],$this->user['storage_type'],$this->user['project_location']);
41 $lists['list'][$k] = $v; 41 $lists['list'][$k] = $v;
42 } 42 }
43 } 43 }
@@ -54,10 +54,12 @@ class AiBlogController extends BaseController @@ -54,10 +54,12 @@ class AiBlogController extends BaseController
54 public function sendTask(AiBlogLogic $aiBlogLogic){ 54 public function sendTask(AiBlogLogic $aiBlogLogic){
55 $this->request->validate([ 55 $this->request->validate([
56 'keyword'=>['required'], 56 'keyword'=>['required'],
57 - 'type'=>['required'] 57 + 'type'=>['required'],
  58 + 'route'=>['required']
58 ],[ 59 ],[
59 'keyword.required' => '关键字不能为空', 60 'keyword.required' => '关键字不能为空',
60 'type.required' => '场景不能为空', 61 'type.required' => '场景不能为空',
  62 + 'route.required' => '路由不能为空',
61 ]); 63 ]);
62 //获取当前项目的ai_blog设置 64 //获取当前项目的ai_blog设置
63 $result = $aiBlogLogic->sendTask(); 65 $result = $aiBlogLogic->sendTask();
@@ -121,6 +121,10 @@ class ComController extends BaseController @@ -121,6 +121,10 @@ class ComController extends BaseController
121 if($is_comment != 1){ 121 if($is_comment != 1){
122 $info['role_menu'] = trim(str_replace(',55,',',',','.$info['role_menu'].','),','); 122 $info['role_menu'] = trim(str_replace(',55,',',',','.$info['role_menu'].','),',');
123 } 123 }
  124 + $is_blogs = $this->getIsBlog();
  125 + if($is_blogs != 1){
  126 + $info['role_menu'] = trim(str_replace(',57,',',',','.$info['role_menu'].','),',');
  127 + }
124 $this->map = [ 128 $this->map = [
125 'status'=>0, 129 'status'=>0,
126 'is_role'=>0, 130 'is_role'=>0,
@@ -165,6 +169,10 @@ class ComController extends BaseController @@ -165,6 +169,10 @@ class ComController extends BaseController
165 if($is_comment != 1){ 169 if($is_comment != 1){
166 $data[] = 55; 170 $data[] = 55;
167 } 171 }
  172 + $is_ai_blog = $this->getIsAiBlog();
  173 + if($is_ai_blog != 1){
  174 + $data[] = 57;
  175 + }
168 if(!empty($data)){ 176 if(!empty($data)){
169 $this->map['id'] = ['not in',$data]; 177 $this->map['id'] = ['not in',$data];
170 } 178 }
@@ -236,7 +244,7 @@ class ComController extends BaseController @@ -236,7 +244,7 @@ class ComController extends BaseController
236 244
237 245
238 public function getIsSubscribe(){ 246 public function getIsSubscribe(){
239 - return $this->project['is_subscribe']; 247 + return $this->project['is_subscribe'] ?? 0;
240 } 248 }
241 249
242 /** 250 /**
@@ -251,26 +259,33 @@ class ComController extends BaseController @@ -251,26 +259,33 @@ class ComController extends BaseController
251 } 259 }
252 260
253 /** 261 /**
  262 + * @remark :是否开启了ai——blog
  263 + * @name :getIsAiBlog
  264 + * @author :lyh
  265 + * @method :post
  266 + * @time :2025/2/19 9:39
  267 + */
  268 + public function getIsAiBlog(){
  269 + return $this->user['is_ai_blog'] ?? 0;
  270 + }
  271 +
  272 +
  273 + /**
254 * @name :登录用户编辑资料/修改密码 274 * @name :登录用户编辑资料/修改密码
255 * @author :liyuhang 275 * @author :liyuhang
256 * @method 276 * @method
257 */ 277 */
258 public function edit_info(){ 278 public function edit_info(){
259 $this->request->validate([ 279 $this->request->validate([
260 -// 'oldPassword'=>'required',  
261 'password' => 'required', 280 'password' => 'required',
262 'confirm'=>'required', 281 'confirm'=>'required',
263 ], [ 282 ], [
264 -// 'oldPassword.required' => '请输入原密码',  
265 'password.required' => '请输入新密码', 283 'password.required' => '请输入新密码',
266 'confirm.required' => '请再次输入新密码', 284 'confirm.required' => '请再次输入新密码',
267 ]); 285 ]);
268 //查询员密码是否正确 286 //查询员密码是否正确
269 $userModel = new User(); 287 $userModel = new User();
270 $info = $userModel->read(['id'=>$this->user['id']]); 288 $info = $userModel->read(['id'=>$this->user['id']]);
271 -// if($info['password'] != base64_encode(md5($this->param['oldPassword']))){  
272 -// $this->response('原密码错误',Code::USER_ERROR);  
273 -// }  
274 if($this->param['password'] != $this->param['confirm']){ 289 if($this->param['password'] != $this->param['confirm']){
275 $this->response('两次密码不一致'); 290 $this->response('两次密码不一致');
276 } 291 }
@@ -408,7 +423,6 @@ class ComController extends BaseController @@ -408,7 +423,6 @@ class ComController extends BaseController
408 */ 423 */
409 public function month_counts(){ 424 public function month_counts(){
410 shell_exec('php artisan month_project '.$this->user['project_id']); 425 shell_exec('php artisan month_project '.$this->user['project_id']);
411 -// Artisan::call('month_project '.$this->user['project_id']);  
412 $this->response('重新刷新中,请稍后刷新查询'); 426 $this->response('重新刷新中,请稍后刷新查询');
413 } 427 }
414 } 428 }
@@ -77,6 +77,9 @@ class SuppliersController extends BaseController @@ -77,6 +77,9 @@ class SuppliersController extends BaseController
77 if(isset($res['status_code']) && $res['status_code'] != 200){ 77 if(isset($res['status_code']) && $res['status_code'] != 200){
78 $this->response($res['message'],Code::SYSTEM_ERROR); 78 $this->response($res['message'],Code::SYSTEM_ERROR);
79 } 79 }
  80 + if(isset($res['data']['image']) && !empty($res['data']['image'])){
  81 + $res['data']['image'] = str_replace('admin.hagro.cn','fob.ai.cc',$res['data']['image']??'');
  82 + }
80 return $this->success($res['data'] ?? []); 83 return $this->success($res['data'] ?? []);
81 } 84 }
82 /** 85 /**
@@ -134,8 +137,12 @@ class SuppliersController extends BaseController @@ -134,8 +137,12 @@ class SuppliersController extends BaseController
134 if(isset($this->param['position'])){ 137 if(isset($this->param['position'])){
135 $param['position'] = $this->param['position']; 138 $param['position'] = $this->param['position'];
136 } 139 }
137 - $res = $this->_action($api_url,$action_name,$param);  
138 - $this->response('success',Code::SUCCESS,$res); 140 + try {
  141 + $res = $this->_action($api_url,$action_name,$param);
  142 + $this->response('success',Code::SUCCESS,$res);
  143 + }catch (\Exception $e){
  144 + $this->fail('请求失败,请联系管理员');
  145 + }
139 } 146 }
140 147
141 /** 148 /**
@@ -253,4 +260,5 @@ class SuppliersController extends BaseController @@ -253,4 +260,5 @@ class SuppliersController extends BaseController
253 $res = $this->_action($api_url,$action_name,$param); 260 $res = $this->_action($api_url,$action_name,$param);
254 $this->response('success',Code::SUCCESS,$res); 261 $this->response('success',Code::SUCCESS,$res);
255 } 262 }
  263 +
256 } 264 }
@@ -172,7 +172,7 @@ class InquiryInfoLogic extends BaseLogic @@ -172,7 +172,7 @@ class InquiryInfoLogic extends BaseLogic
172 * @time :2023/7/13 14:39 172 * @time :2023/7/13 14:39
173 */ 173 */
174 public function inquiryForward($post_data){ 174 public function inquiryForward($post_data){
175 - $url = 'https://form.globalso.com/api/external-interface/add/fa043f9cbec6b38f'; 175 + $url = 'https://www.globalso.site/api/external-interface/add/fa043f9cbec6b38f';
176 $post_data_new = []; 176 $post_data_new = [];
177 $post_data_new['refer'] = $post_data['url']; 177 $post_data_new['refer'] = $post_data['url'];
178 $post_data_new['name'] = $post_data['name']; 178 $post_data_new['name'] = $post_data['name'];
@@ -161,10 +161,10 @@ class ProjectLogic extends BaseLogic @@ -161,10 +161,10 @@ class ProjectLogic extends BaseLogic
161 $this->createProjectData($this->param); 161 $this->createProjectData($this->param);
162 //双向绑定服务器,需放到保存项目的上方 162 //双向绑定服务器,需放到保存项目的上方
163 $this->setServers($this->param['serve_id'],$this->param['id']); 163 $this->setServers($this->param['serve_id'],$this->param['id']);
164 - //保存项目信息  
165 - $this->saveProject($this->param);  
166 //ai_blog 164 //ai_blog
167 $this->setAiBlog($this->param['id'],$this->param['main_lang_id'],$this->param['is_ai_blog'],$this->param['title']); 165 $this->setAiBlog($this->param['id'],$this->param['main_lang_id'],$this->param['is_ai_blog'],$this->param['title']);
  166 + //保存项目信息
  167 + $this->saveProject($this->param);
168 //保存建站部署信息 168 //保存建站部署信息
169 $this->saveProjectDeployBuild($this->param['deploy_build']); 169 $this->saveProjectDeployBuild($this->param['deploy_build']);
170 //保存付费信息 170 //保存付费信息
@@ -202,7 +202,7 @@ class ProjectLogic extends BaseLogic @@ -202,7 +202,7 @@ class ProjectLogic extends BaseLogic
202 return true; 202 return true;
203 } 203 }
204 $projectModel = new Project(); 204 $projectModel = new Project();
205 - $projectInfo = $projectModel->read(['id'=>$project_id],['is_ai_blog','main_lang_id']); 205 + $projectInfo = $projectModel->read(['id'=>$project_id],['title','is_ai_blog','main_lang_id','company']);
206 //获取项目主语种 206 //获取项目主语种
207 $languageModel = new WebLanguage(); 207 $languageModel = new WebLanguage();
208 $languageInfo = $languageModel->read(['id'=>$main_lang_id],['short']); 208 $languageInfo = $languageModel->read(['id'=>$main_lang_id],['short']);
@@ -770,7 +770,6 @@ class ProjectLogic extends BaseLogic @@ -770,7 +770,6 @@ class ProjectLogic extends BaseLogic
770 * @time :2023/9/4 14:29 770 * @time :2023/9/4 14:29
771 */ 771 */
772 public function editDomainStatus($domain,$project_id){ 772 public function editDomainStatus($domain,$project_id){
773 -  
774 $projectOptimize = new DeployOptimize(); 773 $projectOptimize = new DeployOptimize();
775 $optimizeInfo = $projectOptimize->read(['project_id'=>$project_id],['domain']); 774 $optimizeInfo = $projectOptimize->read(['project_id'=>$project_id],['domain']);
776 if($optimizeInfo['domain'] == $domain){ 775 if($optimizeInfo['domain'] == $domain){
@@ -818,6 +817,12 @@ class ProjectLogic extends BaseLogic @@ -818,6 +817,12 @@ class ProjectLogic extends BaseLogic
818 * @time :2023/11/8 14:23 817 * @time :2023/11/8 14:23
819 */ 818 */
820 public function copyProject(){ 819 public function copyProject(){
  820 + //查看当前是否有执行任务
  821 + $noticeModel = new NoticeLog();
  822 + $info = $noticeModel->read(['type'=>NoticeLog::TYPE_COPY_PROJECT,'status'=>0,'data'=>['like','%"'.$this->param['project_id'].'"%']]);
  823 + if($info !== false){
  824 + return $this->success('当前项目已在复制中');
  825 + }
821 NoticeLog::createLog(NoticeLog::TYPE_COPY_PROJECT, ['project_id' => $this->param['project_id']]); 826 NoticeLog::createLog(NoticeLog::TYPE_COPY_PROJECT, ['project_id' => $this->param['project_id']]);
822 return $this->success('项目复制中,请稍后前往初始化项目查看;'); 827 return $this->success('项目复制中,请稍后前往初始化项目查看;');
823 } 828 }
@@ -971,9 +976,7 @@ class ProjectLogic extends BaseLogic @@ -971,9 +976,7 @@ class ProjectLogic extends BaseLogic
971 public function saveWebTrafficConfig($config){ 976 public function saveWebTrafficConfig($config){
972 $config['main_countries'] = textareaToArr($config['main_countries']); 977 $config['main_countries'] = textareaToArr($config['main_countries']);
973 $config['filter_countries'] = textareaToArr($config['filter_countries']); 978 $config['filter_countries'] = textareaToArr($config['filter_countries']);
974 -  
975 $ip_area = InquiryIP::getIpAreas(); 979 $ip_area = InquiryIP::getIpAreas();
976 -  
977 foreach ($config['main_countries'] as $v) { 980 foreach ($config['main_countries'] as $v) {
978 if (!in_array($v, $ip_area)) { 981 if (!in_array($v, $ip_area)) {
979 throw new AsideGlobalException(Code::SYSTEM_ERROR, '[' . $v . ']不存在,请检查后再次提交'); 982 throw new AsideGlobalException(Code::SYSTEM_ERROR, '[' . $v . ']不存在,请检查后再次提交');
@@ -984,11 +987,8 @@ class ProjectLogic extends BaseLogic @@ -984,11 +987,8 @@ class ProjectLogic extends BaseLogic
984 throw new AsideGlobalException(Code::SYSTEM_ERROR, '[' . $v . ']不存在,请检查后再次提交'); 987 throw new AsideGlobalException(Code::SYSTEM_ERROR, '[' . $v . ']不存在,请检查后再次提交');
985 } 988 }
986 } 989 }
987 -  
988 -  
989 $config['main_countries'] = json_encode($config['main_countries']); 990 $config['main_countries'] = json_encode($config['main_countries']);
990 $config['filter_countries'] = json_encode($config['filter_countries']); 991 $config['filter_countries'] = json_encode($config['filter_countries']);
991 -  
992 $model = WebTrafficConfig::where('project_id', $config['project_id'])->first(); 992 $model = WebTrafficConfig::where('project_id', $config['project_id'])->first();
993 if (!$model) { 993 if (!$model) {
994 $model = new WebTrafficConfig(); 994 $model = new WebTrafficConfig();
@@ -996,9 +996,7 @@ class ProjectLogic extends BaseLogic @@ -996,9 +996,7 @@ class ProjectLogic extends BaseLogic
996 } else { 996 } else {
997 $model->edit($config, ['project_id' => $config['project_id']]); 997 $model->edit($config, ['project_id' => $config['project_id']]);
998 } 998 }
999 -  
1000 Cache::forget(WebTrafficConfig::cacheKey($config['project_id'])); 999 Cache::forget(WebTrafficConfig::cacheKey($config['project_id']));
1001 -  
1002 return $this->success(); 1000 return $this->success();
1003 } 1001 }
1004 1002
@@ -1080,6 +1078,4 @@ class ProjectLogic extends BaseLogic @@ -1080,6 +1078,4 @@ class ProjectLogic extends BaseLogic
1080 } 1078 }
1081 return true; 1079 return true;
1082 } 1080 }
1083 -  
1084 -  
1085 } 1081 }
@@ -55,9 +55,7 @@ class AiBlogLogic extends BaseLogic @@ -55,9 +55,7 @@ class AiBlogLogic extends BaseLogic
55 $aiBlogService = new AiBlogService(); 55 $aiBlogService = new AiBlogService();
56 $aiBlogService->mch_id = $aiSettingInfo['mch_id']; 56 $aiBlogService->mch_id = $aiSettingInfo['mch_id'];
57 $aiBlogService->key = $aiSettingInfo['key']; 57 $aiBlogService->key = $aiSettingInfo['key'];
58 - if(!empty($this->param['route'])){  
59 - $aiBlogService->route = generateRoute(Translate::tran($this->param['route'], 'en'));  
60 - } 58 + $aiBlogService->route = generateRoute(Translate::tran($this->param['route'], 'en'));
61 $result = $aiBlogService->createTask($this->param['keyword'],$this->param['type']); 59 $result = $aiBlogService->createTask($this->param['keyword'],$this->param['type']);
62 if($result['status'] == 200){ 60 if($result['status'] == 200){
63 $aiBlogTaskModel = new AiBlogTask(); 61 $aiBlogTaskModel = new AiBlogTask();
@@ -149,6 +149,11 @@ class CategoryLogic extends BaseLogic @@ -149,6 +149,11 @@ class CategoryLogic extends BaseLogic
149 }else{ 149 }else{
150 $param['describe_image'] = json_encode([]); 150 $param['describe_image'] = json_encode([]);
151 } 151 }
  152 + if(isset($param['cate_tak']) && !empty($param['cate_tak'])){
  153 + $param['cate_tak'] = json_encode($param['cate_tak']);
  154 + }else{
  155 + $param['cate_tak'] = json_encode([]);;
  156 + }
152 return $this->success($param); 157 return $this->success($param);
153 } 158 }
154 159
@@ -262,6 +262,7 @@ class UserLoginLogic @@ -262,6 +262,7 @@ class UserLoginLogic
262 $info['is_show_blog'] = $project['is_show_blog']; 262 $info['is_show_blog'] = $project['is_show_blog'];
263 $info['upload_config'] = $project['upload_config']; 263 $info['upload_config'] = $project['upload_config'];
264 $info['main_lang_id'] = $project['main_lang_id']; 264 $info['main_lang_id'] = $project['main_lang_id'];
  265 + $info['is_ai_blog'] = $project['is_ai_blog'];
265 $info['image_max'] = $project['image_max']; 266 $info['image_max'] = $project['image_max'];
266 $info['is_del_inquiry'] = $project['is_del_inquiry'] ?? 0; 267 $info['is_del_inquiry'] = $project['is_del_inquiry'] ?? 0;
267 $info['uptime_type'] = $this->getHistory($project); 268 $info['uptime_type'] = $this->getHistory($project);
@@ -153,4 +153,16 @@ class DomainInfo extends Base @@ -153,4 +153,16 @@ class DomainInfo extends Base
153 $value = Arr::s2a($value); 153 $value = Arr::s2a($value);
154 return $value; 154 return $value;
155 } 155 }
  156 +
  157 + public static function getCacheInfoByProjectId($project_id){
  158 + $cache_key = 'DOMAIN_INFO_BY_PROJECT_ID_' . $project_id;
  159 + $data = Cache::get($cache_key);
  160 + if(!$data){
  161 + $data = DomainInfo::where('project_id', $project_id)->first();
  162 + if($data){
  163 + Cache::put($cache_key, $data, 3600);
  164 + }
  165 + }
  166 + return $data;
  167 + }
156 } 168 }
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: zhl
  5 + * Date: 2025/2/17
  6 + * Time: 11:49
  7 + */
  8 +namespace App\Models\Inquiry;
  9 +
  10 +use App\Models\Base;
  11 +
  12 +/**
  13 + * Class InquiryProject
  14 + * @package App\Models\Inquiry
  15 + */
  16 +class InquiryProject extends Base
  17 +{
  18 + /**
  19 + * @var string 数据表
  20 + */
  21 + protected $table = 'gl_inquiry_project';
  22 +
  23 + // 对应系统版本号
  24 + const VERSION_FOUR = 4;
  25 + const VERSION_FIVE = 5;
  26 + const VERSION_SIX = 6;
  27 +
  28 + /**
  29 + * 保存项目信息
  30 + * @param $version
  31 + * @param $primary_id
  32 + * @param $project
  33 + * @param $channel
  34 + * @param $domain
  35 + * @param int $is_split
  36 + * @param string $test_domain
  37 + * @return InquiryProject
  38 + */
  39 + public static function saveProject($version, $primary_id, $project, $channel, $domain, $is_split = 0, $test_domain = '')
  40 + {
  41 + $date = date('Ymd');
  42 + $log = self::where(compact('version', 'primary_id'))->first();
  43 + if ($log) {
  44 + $log->date = $date;
  45 + $log->save();
  46 + return $log;
  47 + }
  48 + $self = new self();
  49 + $self->version = $version;
  50 + $self->primary_id = $primary_id;
  51 + $self->project = $project;
  52 + $self->channel = $channel;
  53 + $self->domain = $domain;
  54 + $self->is_split = $is_split;
  55 + $self->test_domain = $test_domain;
  56 + $self->date = $date;
  57 + $self->save();
  58 + return $self;
  59 + }
  60 +}
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: zhl
  5 + * Date: 2025/2/17
  6 + * Time: 15:04
  7 + */
  8 +namespace App\Models\Inquiry;
  9 +
  10 +use App\Models\Base;
  11 +
  12 +/**
  13 + * Class InquiryProjectRoute
  14 + * @package App\Models\Inquiry
  15 + */
  16 +class InquiryProjectRoute extends Base
  17 +{
  18 + /**
  19 + * @var string 数据表
  20 + */
  21 + protected $table = 'gl_inquiry_project_route';
  22 +
  23 + /**
  24 + * 保存路由信息
  25 + * @param int $project_id gl_inquiry_project 表ID
  26 + * @param $title
  27 + * @param $route
  28 + * @return InquiryProjectRoute
  29 + */
  30 + public static function saveProjectRoute($project_id, $title, $route)
  31 + {
  32 + $date = date('Ymd');
  33 + $log = self::where(compact('project_id', 'title'))->first();
  34 + if ($log) {
  35 + $log->date = $date;
  36 + $log->save();
  37 + return $log;
  38 + }
  39 +
  40 + $self = new self();
  41 + $self->project_id = $project_id;
  42 + $self->title = $title;
  43 + $self->route = $route;
  44 + $self->date = $date;
  45 + $self->save();
  46 + return $self;
  47 + }
  48 +}
@@ -33,6 +33,19 @@ class Category extends Base @@ -33,6 +33,19 @@ class Category extends Base
33 } 33 }
34 34
35 /** 35 /**
  36 + * @remark :获取tdk
  37 + * @name :getCateTdkAttribute
  38 + * @author :lyh
  39 + * @method :post
  40 + * @time :2025/2/19 11:03
  41 + */
  42 + public function getCateTdkAttribute($value){
  43 + if(!empty($value)){
  44 + $value = Arr::s2a($value);
  45 + }
  46 + return $value;
  47 + }
  48 + /**
36 * 根据产品分类获取分类列表和产品 49 * 根据产品分类获取分类列表和产品
37 */ 50 */
38 public static function getCategoryBySelfCategory($projectId,$routerMap) 51 public static function getCategoryBySelfCategory($projectId,$routerMap)
@@ -20,7 +20,6 @@ class Project extends Base @@ -20,7 +20,6 @@ class Project extends Base
20 const DATABASE_NAME_FIX = 'gl_data_'; 20 const DATABASE_NAME_FIX = 'gl_data_';
21 const CUSTOMIZED_ONE = 1;//定制项目 21 const CUSTOMIZED_ONE = 1;//定制项目
22 const DEMO_PROJECT_ID = 1; 22 const DEMO_PROJECT_ID = 1;
23 -  
24 const STATUS_ONE = 1;//审核通过 23 const STATUS_ONE = 1;//审核通过
25 const TYPE_ZERO = 0;//初始导入项目 24 const TYPE_ZERO = 0;//初始导入项目
26 const TYPE_ONE = 1;//建站中 25 const TYPE_ONE = 1;//建站中
@@ -29,10 +28,8 @@ class Project extends Base @@ -29,10 +28,8 @@ class Project extends Base
29 const TYPE_FOUR = 4;//推广续费 28 const TYPE_FOUR = 4;//推广续费
30 const TYPE_FIVE = 5;//未续费网站 29 const TYPE_FIVE = 5;//未续费网站
31 const TYPE_SIX = 6;//特殊推广项目 30 const TYPE_SIX = 6;//特殊推广项目
32 -  
33 const TYPE_SEVEN = 7;//错误单 31 const TYPE_SEVEN = 7;//错误单
34 const MYSQL_ID = 2;//默认数据库id 32 const MYSQL_ID = 2;//默认数据库id
35 -  
36 const IS_UPGRADE_FALSE = 0; 33 const IS_UPGRADE_FALSE = 0;
37 const IS_UPGRADE_TRUE = 1; 34 const IS_UPGRADE_TRUE = 1;
38 35
@@ -58,10 +55,11 @@ class Project extends Base @@ -58,10 +55,11 @@ class Project extends Base
58 } 55 }
59 56
60 /** 57 /**
61 - * 项目分类 58 + * 项目类型
62 * @return string[] 59 * @return string[]
63 * @author zbj 60 * @author zbj
64 * @date 2023/4/26 61 * @date 2023/4/26
  62 + * @remark project表中(extend_type + type)的属性值
65 */ 63 */
66 public static function typeMap() 64 public static function typeMap()
67 { 65 {
@@ -23,7 +23,7 @@ class InquiryRelayService @@ -23,7 +23,7 @@ class InquiryRelayService
23 { 23 {
24 $date = date('Y-m-d'); 24 $date = date('Y-m-d');
25 $token = md5($date . 'qqs'); 25 $token = md5($date . 'qqs');
26 - $url = 'https://form.globalso.com/api/external-interface/echo_inquriy/d1483a8e57cb485a?date=' . $date . '&token=' . $token . '&type=2'; 26 + $url = 'https://www.globalso.site/api/external-interface/echo_inquriy/d1483a8e57cb485a?date=' . $date . '&token=' . $token . '&type=2';
27 $result = http_get($url); 27 $result = http_get($url);
28 return $result; 28 return $result;
29 } 29 }
@@ -105,4 +105,8 @@ class InquiryRelayService @@ -105,4 +105,8 @@ class InquiryRelayService
105 curl_close($ch); 105 curl_close($ch);
106 return $result; 106 return $result;
107 } 107 }
  108 +
  109 +########################################################################################################################
  110 +# 询盘结束, 同步项目及路由 #
  111 +########################################################################################################################
108 } 112 }
@@ -29,7 +29,7 @@ class SyncService @@ -29,7 +29,7 @@ class SyncService
29 public function projectAcceptAddress($project_id = 0) 29 public function projectAcceptAddress($project_id = 0)
30 { 30 {
31 try { 31 try {
32 - $url = 'https://form.globalso.com/api/globalsov6'; 32 + $url = 'https://www.globalso.site/api/globalsov6';
33 // 项目信息 33 // 项目信息
34 $project = Project::with('deploy_build')->with('deploy_optimize')->where(['id'=>$project_id])->first(); 34 $project = Project::with('deploy_build')->with('deploy_optimize')->where(['id'=>$project_id])->first();
35 // 不满足条件 不同步到表单系统 35 // 不满足条件 不同步到表单系统
@@ -75,7 +75,7 @@ class SyncSubmitTaskService @@ -75,7 +75,7 @@ class SyncSubmitTaskService
75 } 75 }
76 76
77 //域名 过滤国家或ip 77 //域名 过滤国家或ip
78 - $domain_info = DomainInfo::where('project_id', $project['id'])->first(); 78 + $domain_info = DomainInfo::getCacheInfoByProjectId($project['id']);
79 if(!empty($domain_info['not_allow_country'])){ 79 if(!empty($domain_info['not_allow_country'])){
80 $not_allow_countries = CountryCode::whereIn('id', $domain_info['not_allow_country'])->pluck('c_name')->toArray(); 80 $not_allow_countries = CountryCode::whereIn('id', $domain_info['not_allow_country'])->pluck('c_name')->toArray();
81 if(in_array($data['country'], $not_allow_countries)){ 81 if(in_array($data['country'], $not_allow_countries)){
@@ -88,9 +88,11 @@ class SyncSubmitTaskService @@ -88,9 +88,11 @@ class SyncSubmitTaskService
88 } 88 }
89 } 89 }
90 90
  91 + $time = time();
91 if(!ProjectServer::useProject($project['id'])){ 92 if(!ProjectServer::useProject($project['id'])){
92 return false; 93 return false;
93 } 94 }
  95 + echo date('Y-m-d H:i:s') . ' | useProject time:' . (time() - $time) . PHP_EOL;
94 96
95 $action = $task['type']; 97 $action = $task['type'];
96 98
@@ -106,7 +108,7 @@ class SyncSubmitTaskService @@ -106,7 +108,7 @@ class SyncSubmitTaskService
106 } 108 }
107 $filed == 'email' && $action = 'subscribe'; 109 $filed == 'email' && $action = 'subscribe';
108 } 110 }
109 - 111 +
110 $handler = new self(); 112 $handler = new self();
111 return $handler->$action($data, $date, $task['id'], $task['traffic']); 113 return $handler->$action($data, $date, $task['id'], $task['traffic']);
112 } 114 }
@@ -297,6 +299,17 @@ class SyncSubmitTaskService @@ -297,6 +299,17 @@ class SyncSubmitTaskService
297 if(!$ip){ 299 if(!$ip){
298 return ''; 300 return '';
299 } 301 }
  302 +
  303 +// $client = new \GuzzleHttp\Client();
  304 +// $res = $client->request('GET', "http://ip.globalso.com?ip=".$ip, [
  305 +// 'proxy' => env('CURL_PROXY'), // 代理服务器地址和端口号
  306 +// ]);
  307 +// if($res->getStatusCode() == 200){
  308 +// return $res->getBody()->getContents();
  309 +// }else{
  310 +// return '';
  311 +// }
  312 +
300 $res = Http::withoutVerifying()->get('http://ip.globalso.com', ['ip' => $ip]); 313 $res = Http::withoutVerifying()->get('http://ip.globalso.com', ['ip' => $ip]);
301 if($res->status() == 200){ 314 if($res->status() == 200){
302 return $res->body(); 315 return $res->body();
@@ -334,7 +347,9 @@ class SyncSubmitTaskService @@ -334,7 +347,9 @@ class SyncSubmitTaskService
334 if($ip == "127.0.0.1"){ 347 if($ip == "127.0.0.1"){
335 throw new InquiryFilterException('127.0.0.1过滤'); 348 throw new InquiryFilterException('127.0.0.1过滤');
336 } 349 }
  350 + $time = time();
337 $country = self::getCountryByIp($ip); 351 $country = self::getCountryByIp($ip);
  352 + echo date('Y-m-d H:i:s') . ' | getCountryByIp time:' . (time() - $time) . PHP_EOL;
338 //访问记录过滤国内 353 //访问记录过滤国内
339 if ($type == SyncSubmitTask::TYPE_VISIT && $country == "中国" && !$project->is_record_china_visit){ 354 if ($type == SyncSubmitTask::TYPE_VISIT && $country == "中国" && !$project->is_record_china_visit){
340 throw new InquiryFilterException('中国内地过滤'); 355 throw new InquiryFilterException('中国内地过滤');