作者 赵彬吉
@@ -263,6 +263,7 @@ class HtmlCollect extends Command @@ -263,6 +263,7 @@ class HtmlCollect extends Command
263 //判断资源是否需要下载 263 //判断资源是否需要下载
264 protected function url_check($url, $project_id, $domain, $web_url_domain, $home_url) 264 protected function url_check($url, $project_id, $domain, $web_url_domain, $home_url)
265 { 265 {
  266 + $url = trim($url);
266 if ($url) { 267 if ($url) {
267 $url = str_replace('"', '', $url); 268 $url = str_replace('"', '', $url);
268 $arr = parse_url($url); 269 $arr = parse_url($url);
@@ -279,6 +279,7 @@ class HtmlLanguageCollect extends Command @@ -279,6 +279,7 @@ class HtmlLanguageCollect extends Command
279 //判断资源是否需要下载 279 //判断资源是否需要下载
280 protected function url_check($url, $project_id, $domain, $web_url_domain, $home_url) 280 protected function url_check($url, $project_id, $domain, $web_url_domain, $home_url)
281 { 281 {
  282 + $url = trim($url);
282 if ($url) { 283 if ($url) {
283 $url = str_replace('"', '', $url); 284 $url = str_replace('"', '', $url);
284 $arr = parse_url($url); 285 $arr = parse_url($url);
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :CopyProject.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2024/1/9 16:01
  8 + */
  9 +
  10 +namespace App\Events;
  11 +
  12 +use Illuminate\Broadcasting\InteractsWithSockets;
  13 +use Illuminate\Foundation\Events\Dispatchable;
  14 +use Illuminate\Queue\SerializesModels;
  15 +class CopyProject
  16 +{
  17 + use Dispatchable, InteractsWithSockets, SerializesModels;
  18 + public $data;
  19 + /**
  20 + * 监听更新HTML静态页
  21 + */
  22 + public function __construct($data)
  23 + {
  24 + $this->data = $data;
  25 + }
  26 +}
@@ -216,7 +216,9 @@ class OptimizeController extends BaseController @@ -216,7 +216,9 @@ class OptimizeController extends BaseController
216 $query = $query->where('gl_project_deploy_build.test_domain','like','%'.$this->map['test_domain'].'%'); 216 $query = $query->where('gl_project_deploy_build.test_domain','like','%'.$this->map['test_domain'].'%');
217 } 217 }
218 $query = $query->whereIn('gl_project.type',[2,4]);//TODO::2,4代表优化项目 218 $query = $query->whereIn('gl_project.type',[2,4]);//TODO::2,4代表优化项目
219 - $query = $query->where('gl_project_online_check.qa_status',1); 219 + $query->where(function ($subQuery) {
  220 + $subQuery->orwhere('gl_project_online_check.qa_status',1)->orwhere('gl_project.is_upgrade',1);
  221 + });
220 return $query; 222 return $query;
221 } 223 }
222 224
@@ -240,6 +240,7 @@ class ProductController extends BaseController @@ -240,6 +240,7 @@ class ProductController extends BaseController
240 } 240 }
241 $v['status_text'] = Product::statusMap()[$v['status']] ?? ''; 241 $v['status_text'] = Product::statusMap()[$v['status']] ?? '';
242 //获取当前用户选择的模版 242 //获取当前用户选择的模版
  243 + $v['video'] = json_decode($v['video']);
243 $template_id = $this->getTemplateId(BTemplate::SOURCE_PRODUCT,BTemplate::IS_DETAIL); 244 $template_id = $this->getTemplateId(BTemplate::SOURCE_PRODUCT,BTemplate::IS_DETAIL);
244 $v['is_renovation'] = $this->getIsRenovation(BTemplate::SOURCE_PRODUCT,BTemplate::IS_DETAIL,$template_id,$v['id']); 245 $v['is_renovation'] = $this->getIsRenovation(BTemplate::SOURCE_PRODUCT,BTemplate::IS_DETAIL,$template_id,$v['id']);
245 $v['url'] = $this->user['domain'].$v['route']; 246 $v['url'] = $this->user['domain'].$v['route'];
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 namespace App\Http\Logic\Aside\Project; 3 namespace App\Http\Logic\Aside\Project;
4 4
5 use App\Enums\Common\Code; 5 use App\Enums\Common\Code;
  6 +use App\Events\CopyProject;
6 use App\Exceptions\AsideGlobalException; 7 use App\Exceptions\AsideGlobalException;
7 use App\Models\Com\NoticeLog; 8 use App\Models\Com\NoticeLog;
8 use App\Models\Com\UpdateLog; 9 use App\Models\Com\UpdateLog;
@@ -567,128 +568,8 @@ class ProjectLogic extends BaseLogic @@ -567,128 +568,8 @@ class ProjectLogic extends BaseLogic
567 * @time :2023/11/8 14:23 568 * @time :2023/11/8 14:23
568 */ 569 */
569 public function copyProject(){ 570 public function copyProject(){
570 - DB::beginTransaction();  
571 - try {  
572 - //复制初始项目  
573 - $data = $this->model::where('id', $this->param['project_id'])->first();  
574 - $data = $data->getAttributes();  
575 - $type = $data['type'];  
576 - $data['type'] = 0;  
577 - $data['title'] = $data['title'].'-copy';  
578 - unset($data['id']);  
579 - $project_id = $this->model->insertGetId($data);  
580 - //复制部署表  
581 - $buildModel = new DeployBuild();  
582 - $buildData = $buildModel::where('project_id', $this->param['project_id'])->first();  
583 - if(!empty($buildData)){  
584 - $buildData = $buildData->getAttributes();  
585 - $buildData['project_id'] = $project_id;  
586 - $hashids = new Hashids('test_domain', 5, 'abcdefghjkmnpqrstuvwxyz1234567890');  
587 - $code = $hashids->encode($project_id);  
588 - $buildData['test_domain'] = 'https://v6-' . $code . '.globalso.site/';  
589 - unset($buildData['id']);  
590 - $buildModel->insert($buildData);  
591 - }  
592 - //复制优化表  
593 - $optimizeModel = new DeployOptimize();  
594 - $optimizeData = $optimizeModel::where('project_id', $this->param['project_id'])->first();  
595 - if(!empty($optimizeData)){  
596 - $optimizeData = $optimizeData->getAttributes();  
597 - unset($optimizeData['id'],$optimizeData['domain']);  
598 - $optimizeData['project_id'] = $project_id;  
599 - $optimizeModel->insert($optimizeData);  
600 - }  
601 - //复制付费表  
602 - $paymentModel = new Payment();  
603 - $paymentData = $paymentModel::where('project_id', $this->param['project_id'])->first();  
604 - if(!empty($paymentData)){  
605 - $paymentData = $paymentData->getAttributes();  
606 - unset($paymentData['id']);  
607 - $paymentData['project_id'] = $project_id;  
608 - $paymentModel->insert($paymentData);  
609 - }  
610 - //复制售后表  
611 - $afterModel = new After();  
612 - $afterData = $afterModel::where('project_id', $this->param['project_id'])->first();  
613 - if(!empty($afterData)){  
614 - $afterData = $afterData->getAttributes();  
615 - unset($afterData['id']);  
616 - $afterData['project_id'] = $project_id;  
617 - $afterModel->insert($afterData);  
618 - }  
619 - //复制用户  
620 - $userModel = new UserModel();  
621 - $userData = $userModel::where('project_id', $this->param['project_id'])->where('role_id',0)->first();  
622 - if(!empty($userData)){  
623 - $userData = $userData->getAttributes();  
624 - unset($userData['id']);  
625 - $userData['project_id'] = $project_id;  
626 - $userModel->insert($userData);  
627 - }  
628 - //复制设置的模版  
629 - $settingTemplateModel = new Setting();  
630 - $settingData = $settingTemplateModel::where('project_id', $this->param['project_id'])->first();  
631 - if(!empty($settingData)){  
632 - $settingData = $settingData->getAttributes();  
633 - unset($settingData['id']);  
634 - $settingData['project_id'] = $project_id;  
635 - $settingTemplateModel->insert($settingData);  
636 - }  
637 - DB::commit();  
638 - }catch (\Exception $e){  
639 - DB::rollBack();  
640 - $this->fail('error');  
641 - }  
642 - if($type != 0){  
643 - $this->copyMysql($this->param['project_id'],$project_id);  
644 - }  
645 - return $this->success($data);  
646 - }  
647 -  
648 - //复制数据库  
649 - public function copyMysql($project_id,$new_project_id){  
650 - //切换数据库配置  
651 - $project = ProjectServer::useProject($new_project_id);  
652 - //创建数据库  
653 - ProjectServer::createDatabase($project);  
654 - //创建表  
655 - $this->initTable($project_id,$new_project_id);  
656 - }  
657 -  
658 -  
659 - /**  
660 - * @remark :创建数据库  
661 - * @name :initTable  
662 - * @author :lyh  
663 - * @method :post  
664 - * @time :2023/12/11 10:09  
665 - */  
666 - public function initTable($project_id,$news_project_id)  
667 - {  
668 - config(['database.connections.custom_tmp_mysql_copy.database' => 'gl_data_'.$project_id]);  
669 - $database_name = DB::connection('custom_tmp_mysql_copy')->getDatabaseName();  
670 - $tables = Schema::connection('custom_tmp_mysql_copy')->getAllTables();  
671 - $tables = array_column($tables, 'Tables_in_' . $database_name);  
672 - foreach ($tables as $table) {  
673 - $has_table = Schema::connection('custom_mysql')->hasTable($table);  
674 - if (!$has_table) {  
675 - $sql = DB::connection('custom_tmp_mysql_copy')->select("SHOW CREATE TABLE {$table}");  
676 - DB::connection('custom_mysql')->statement(get_object_vars($sql[0])['Create Table']);  
677 - }  
678 - DB::connection('custom_mysql')->table($table)->truncate(); // 清空目标表数据  
679 - DB::connection('custom_mysql')->table($table)->insertUsing(  
680 - [], // 列名数组,留空表示插入所有列  
681 - function ($query) use ($table,$project_id) {  
682 - $name = 'gl_data_'.$project_id.'.'.$table;  
683 - $query->select('*')->from("{$name}");  
684 - }  
685 - );  
686 -  
687 - if (Schema::connection('custom_mysql')->hasColumn($table, 'project_id')) {  
688 - DB::connection('custom_mysql')->table($table)->update(['project_id' => $news_project_id]);  
689 - }  
690 - }  
691 - return true; 571 + CopyProject::dispatch(['project_id'=>$this->param['project_id']]);
  572 + return $this->success();
692 } 573 }
693 574
694 /** 575 /**
@@ -29,7 +29,7 @@ class CustomTemplateLogic extends BaseLogic @@ -29,7 +29,7 @@ class CustomTemplateLogic extends BaseLogic
29 * @time :2023/6/29 15:46 29 * @time :2023/6/29 15:46
30 */ 30 */
31 public function customTemplateLists($map,$page,$row,$order = 'created_at'){ 31 public function customTemplateLists($map,$page,$row,$order = 'created_at'){
32 - $filed = ['id','name','status','url','title','keywords','description','project_id','is_upgrade','six_read','created_at','updated_at']; 32 + $filed = ['id','name','status','url','title','keywords','description','project_id','is_upgrade','six_read','is_visualization','created_at','updated_at'];
33 $map['deleted_status'] = 0; 33 $map['deleted_status'] = 0;
34 $map['project_id'] = $this->user['project_id']; 34 $map['project_id'] = $this->user['project_id'];
35 $lists = $this->model->lists($map,$page,$row,$order,$filed); 35 $lists = $this->model->lists($map,$page,$row,$order,$filed);
@@ -214,6 +214,9 @@ class CustomModuleCategoryLogic extends BaseLogic @@ -214,6 +214,9 @@ class CustomModuleCategoryLogic extends BaseLogic
214 public function delRoute($id) 214 public function delRoute($id)
215 { 215 {
216 $info = $this->model->read(['id' => $id], ['id', 'route','module_id']); 216 $info = $this->model->read(['id' => $id], ['id', 'route','module_id']);
  217 + if($info === false){
  218 + return $this->success();
  219 + }
217 RouteMap::delRoute(RouteMap::SOURCE_MODULE_CATE, $id, $this->user['project_id']); 220 RouteMap::delRoute(RouteMap::SOURCE_MODULE_CATE, $id, $this->user['project_id']);
218 //通知 221 //通知
219 $this->curlDelRoute(['route'=>$info['route']]); 222 $this->curlDelRoute(['route'=>$info['route']]);
@@ -275,6 +275,11 @@ class ProductLogic extends BaseLogic @@ -275,6 +275,11 @@ class ProductLogic extends BaseLogic
275 $param['gallery'] = Arr::a2s([]); 275 $param['gallery'] = Arr::a2s([]);
276 $param['thumb'] = Arr::a2s([]); 276 $param['thumb'] = Arr::a2s([]);
277 } 277 }
  278 + if(isset($param['video']) && !empty($param['video'])){
  279 + $param['video'] = Arr::a2s($param['video'] ?? []);
  280 + }else{
  281 + $param['video'] = Arr::a2s([]);
  282 + }
278 $param['attrs'] = Arr::a2s($param['attrs'] ?? []); 283 $param['attrs'] = Arr::a2s($param['attrs'] ?? []);
279 $param['attr_id'] = Arr::arrToSet($param['attr_id'] ?? ''); 284 $param['attr_id'] = Arr::arrToSet($param['attr_id'] ?? '');
280 if(isset($param['keyword_id']) && !empty($param['keyword_id'])){ 285 if(isset($param['keyword_id']) && !empty($param['keyword_id'])){
@@ -24,7 +24,7 @@ class CustomTemplateRequest extends FormRequest @@ -24,7 +24,7 @@ class CustomTemplateRequest extends FormRequest
24 public function rules() 24 public function rules()
25 { 25 {
26 return [ 26 return [
27 - 'name'=>'required', 27 + 'name'=>'required|max:255',
28 'url'=>'required', 28 'url'=>'required',
29 'keywords'=>'max:1000', 29 'keywords'=>'max:1000',
30 // 'description'=>'max:500', 30 // 'description'=>'max:500',
  1 +<?php
  2 +
  3 +namespace App\Listeners;
  4 +
  5 +use App\Events\CopyProject;
  6 +use App\Events\UpdateHtml;
  7 +use App\Jobs\updateHtmlJob;
  8 +use App\Models\Project\After;
  9 +use App\Models\Project\DeployBuild;
  10 +use App\Models\Project\DeployOptimize;
  11 +use App\Models\Project\Payment;
  12 +use App\Models\Project\Project;
  13 +use App\Models\Template\Setting;
  14 +use App\Models\User\User as UserModel;
  15 +use App\Services\ProjectServer;
  16 +use Hashids\Hashids;
  17 +use Illuminate\Contracts\Queue\ShouldQueue;
  18 +use Illuminate\Support\Facades\DB;
  19 +use Illuminate\Support\Facades\Schema;
  20 +
  21 +class CopyProjectListener implements ShouldQueue
  22 +{
  23 + public function __construct()
  24 + {
  25 + //
  26 + }
  27 +
  28 + /**
  29 + * Handle the event.
  30 + *
  31 + * @param UpdateHtml $event
  32 + * @return void
  33 + */
  34 + public function handle(CopyProject $event)
  35 + {
  36 + $this->param = $event->data;
  37 + $this->model = new Project();
  38 + DB::beginTransaction();
  39 + try {
  40 + //复制初始项目
  41 + $data = $this->model::where('id', $this->param['project_id'])->first();
  42 + $data = $data->getAttributes();
  43 + $type = $data['type'];
  44 + $data['type'] = 0;
  45 + $data['title'] = $data['title'].'-copy';
  46 + unset($data['id']);
  47 + $project_id = $this->model->insertGetId($data);
  48 + //复制部署表
  49 + $buildModel = new DeployBuild();
  50 + $buildData = $buildModel::where('project_id', $this->param['project_id'])->first();
  51 + if(!empty($buildData)){
  52 + $buildData = $buildData->getAttributes();
  53 + $buildData['project_id'] = $project_id;
  54 + $hashids = new Hashids('test_domain', 5, 'abcdefghjkmnpqrstuvwxyz1234567890');
  55 + $code = $hashids->encode($project_id);
  56 + $buildData['test_domain'] = 'https://v6-' . $code . '.globalso.site/';
  57 + unset($buildData['id']);
  58 + $buildModel->insert($buildData);
  59 + }
  60 + //复制优化表
  61 + $optimizeModel = new DeployOptimize();
  62 + $optimizeData = $optimizeModel::where('project_id', $this->param['project_id'])->first();
  63 + if(!empty($optimizeData)){
  64 + $optimizeData = $optimizeData->getAttributes();
  65 + unset($optimizeData['id'],$optimizeData['domain']);
  66 + $optimizeData['project_id'] = $project_id;
  67 + $optimizeModel->insert($optimizeData);
  68 + }
  69 + //复制付费表
  70 + $paymentModel = new Payment();
  71 + $paymentData = $paymentModel::where('project_id', $this->param['project_id'])->first();
  72 + if(!empty($paymentData)){
  73 + $paymentData = $paymentData->getAttributes();
  74 + unset($paymentData['id']);
  75 + $paymentData['project_id'] = $project_id;
  76 + $paymentModel->insert($paymentData);
  77 + }
  78 + //复制售后表
  79 + $afterModel = new After();
  80 + $afterData = $afterModel::where('project_id', $this->param['project_id'])->first();
  81 + if(!empty($afterData)){
  82 + $afterData = $afterData->getAttributes();
  83 + unset($afterData['id']);
  84 + $afterData['project_id'] = $project_id;
  85 + $afterModel->insert($afterData);
  86 + }
  87 + //复制用户
  88 + $userModel = new UserModel();
  89 + $userData = $userModel::where('project_id', $this->param['project_id'])->where('role_id',0)->first();
  90 + if(!empty($userData)){
  91 + $userData = $userData->getAttributes();
  92 + unset($userData['id']);
  93 + $userData['project_id'] = $project_id;
  94 + $userModel->insert($userData);
  95 + }
  96 + //复制设置的模版
  97 + $settingTemplateModel = new Setting();
  98 + $settingData = $settingTemplateModel::where('project_id', $this->param['project_id'])->first();
  99 + if(!empty($settingData)){
  100 + $settingData = $settingData->getAttributes();
  101 + unset($settingData['id']);
  102 + $settingData['project_id'] = $project_id;
  103 + $settingTemplateModel->insert($settingData);
  104 + }
  105 + DB::commit();
  106 + }catch (\Exception $e){
  107 + DB::rollBack();
  108 + $this->fail('error');
  109 + }
  110 + if($type != 0){
  111 + $this->copyMysql($this->param['project_id'],$project_id);
  112 + }
  113 + return true;
  114 + }
  115 +
  116 + //复制数据库
  117 + public function copyMysql($project_id,$new_project_id){
  118 + //切换数据库配置
  119 + $project = ProjectServer::useProject($new_project_id);
  120 + //创建数据库
  121 + ProjectServer::createDatabase($project);
  122 + //创建表
  123 + $this->initTable($project_id,$new_project_id);
  124 + }
  125 +
  126 + /**
  127 + * @remark :创建数据库
  128 + * @name :initTable
  129 + * @author :lyh
  130 + * @method :post
  131 + * @time :2023/12/11 10:09
  132 + */
  133 + public function initTable($project_id,$news_project_id)
  134 + {
  135 + config(['database.connections.custom_tmp_mysql_copy.database' => 'gl_data_'.$project_id]);
  136 + $database_name = DB::connection('custom_tmp_mysql_copy')->getDatabaseName();
  137 + $tables = Schema::connection('custom_tmp_mysql_copy')->getAllTables();
  138 + $tables = array_column($tables, 'Tables_in_' . $database_name);
  139 + foreach ($tables as $table) {
  140 + $has_table = Schema::connection('custom_mysql')->hasTable($table);
  141 + if (!$has_table) {
  142 + $sql = DB::connection('custom_tmp_mysql_copy')->select("SHOW CREATE TABLE {$table}");
  143 + DB::connection('custom_mysql')->statement(get_object_vars($sql[0])['Create Table']);
  144 + }
  145 + DB::connection('custom_mysql')->table($table)->truncate(); // 清空目标表数据
  146 + DB::connection('custom_mysql')->table($table)->insertUsing(
  147 + [], // 列名数组,留空表示插入所有列
  148 + function ($query) use ($table,$project_id) {
  149 + $name = 'gl_data_'.$project_id.'.'.$table;
  150 + $query->select('*')->from("{$name}");
  151 + }
  152 + );
  153 + if (Schema::connection('custom_mysql')->hasColumn($table, 'project_id')) {
  154 + DB::connection('custom_mysql')->table($table)->update(['project_id' => $news_project_id]);
  155 + }
  156 + }
  157 + return true;
  158 + }
  159 +}
@@ -56,7 +56,7 @@ class CollectTask extends Base @@ -56,7 +56,7 @@ class CollectTask extends Base
56 $new_domain = implode('.', $domain_arr); 56 $new_domain = implode('.', $domain_arr);
57 } else { 57 } else {
58 //二级目录 58 //二级目录
59 - $new_domain = $url_arr['host'] ?? $domain . '/' . $v_lan; 59 + $new_domain = ($url_arr['host'] ?? $domain) . '/' . $v_lan;
60 } 60 }
61 61
62 $data[] = [ 62 $data[] = [
@@ -52,16 +52,8 @@ class Category extends Base @@ -52,16 +52,8 @@ class Category extends Base
52 */ 52 */
53 public static function getProductNum($cate_id){ 53 public static function getProductNum($cate_id){
54 $cate_ids = self::getChildIdsArr($cate_id); 54 $cate_ids = self::getChildIdsArr($cate_id);
55 - $str = 0;  
56 - foreach ($cate_ids as $v){  
57 - $info = self::where('pid',$v)->first();  
58 - if($info){  
59 - continue;  
60 - }else{  
61 - $count = Product::where('category_id','like','%,'.$v.',%')->count();  
62 - $str = $str+$count;  
63 - }  
64 - }  
65 - return $str; 55 + $count = CategoryRelated::whereIn('cate_id',$cate_ids)->count();
  56 +// $str = 0;
  57 + return $count;
66 } 58 }
67 } 59 }
@@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
2 2
3 namespace App\Providers; 3 namespace App\Providers;
4 4
  5 +use App\Events\CopyProject;
  6 +use App\Listeners\CopyProjectListener;
5 use Illuminate\Auth\Events\Registered; 7 use Illuminate\Auth\Events\Registered;
6 use Illuminate\Auth\Listeners\SendEmailVerificationNotification; 8 use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
7 use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; 9 use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
@@ -22,6 +24,7 @@ class EventServiceProvider extends ServiceProvider @@ -22,6 +24,7 @@ class EventServiceProvider extends ServiceProvider
22 'Illuminate\Database\Events\QueryExecuted' => [ 24 'Illuminate\Database\Events\QueryExecuted' => [
23 'App\Listeners\QueryListener', 25 'App\Listeners\QueryListener',
24 ], 26 ],
  27 + CopyProject::class => [CopyProjectListener::class],
25 ]; 28 ];
26 29
27 /** 30 /**
@@ -205,7 +205,7 @@ return [ @@ -205,7 +205,7 @@ return [
205 'Date' => Illuminate\Support\Facades\Date::class, 205 'Date' => Illuminate\Support\Facades\Date::class,
206 'DB' => Illuminate\Support\Facades\DB::class, 206 'DB' => Illuminate\Support\Facades\DB::class,
207 'Eloquent' => Illuminate\Database\Eloquent\Model::class, 207 'Eloquent' => Illuminate\Database\Eloquent\Model::class,
208 - 'Event' => Illuminate\Support\Facades\Event::class, 208 + 'Events' => Illuminate\Support\Facades\Event::class,
209 'File' => Illuminate\Support\Facades\File::class, 209 'File' => Illuminate\Support\Facades\File::class,
210 'Gate' => Illuminate\Support\Facades\Gate::class, 210 'Gate' => Illuminate\Support\Facades\Gate::class,
211 'Hash' => Illuminate\Support\Facades\Hash::class, 211 'Hash' => Illuminate\Support\Facades\Hash::class,