作者 赵彬吉
  1 +<?php
  2 +
  3 +namespace App\Console\Commands\Domain;
  4 +
  5 +use App\Models\Devops\ServersIp;
  6 +use App\Services\AlibabaCloudService;
  7 +use Illuminate\Console\Command;
  8 +
  9 +class EmergencyRecords extends Command
  10 +{
  11 + protected $signature = 'emergency_records {server_id} {type}';
  12 + protected $description = '紧急修改域名解析';
  13 +
  14 + public function handle()
  15 + {
  16 + //服务器id
  17 + $server_id = $this->argument('server_id');
  18 + //类型,1受灾,2恢复
  19 + $type = $this->argument('type');
  20 +
  21 + try {
  22 + //获取服务器的所有可用ip
  23 + $server_ip_model = new ServersIp();
  24 + $server_ip_list = $server_ip_model->where('servers_id', $server_id)->where('status', 0)->get();
  25 + if ($server_ip_list->count() > 0) {
  26 + foreach ($server_ip_list as $value) {
  27 + if (empty($value->ip) || empty($value->domain)) {
  28 + $this->output('ID ' . $value->id . ' 数据错误');
  29 + continue;
  30 + }
  31 +
  32 + //获取解析记录
  33 + $domain_array = explode('.', $value->domain);
  34 + $domain_rr = $domain_array[0];
  35 + $record = AlibabaCloudService::describeDomainRecords('globalso.com', $domain_rr);
  36 + $record_status_code = $record['statusCode'] ?? 0;
  37 + if ($record_status_code != 200) {
  38 + $this->output('获取主机记录 ' . $domain_rr . ' 解析数据失败');
  39 + continue;
  40 + }
  41 + $record_detail = $record['body']['DomainRecords']['Record'][0] ?? [];
  42 + if (!$record_detail) {
  43 + $this->output('主机记录 ' . $domain_rr . ' 解析数据不存在');
  44 + continue;
  45 + }
  46 +
  47 + //目标ip跟解析记录当前ip一样的数据,不用修改
  48 + $target_ip = $type == 1 ? '43.153.1.240' : $value->ip;
  49 + if ($target_ip == $record_detail['Value']) {
  50 + $this->output('主机记录 ' . $domain_rr . ' 的值已为 ' . $target_ip);
  51 + continue;
  52 + }
  53 +
  54 + //修改解析记录
  55 + $record_id = $record_detail['RecordId'];
  56 + $record_rr = $record_detail['RR'];
  57 + $record_type = $record_detail['Type'];
  58 +
  59 + $record_edit = AlibabaCloudService::updateDomainRecord($record_id, $record_rr, $record_type, $target_ip);
  60 + $record_edit_status_code = $record_edit['statusCode'] ?? 0;
  61 + if ($record_edit_status_code == 200) {
  62 + $this->output('修改主机记录 ' . $record_rr . ' 的值为 ' . $target_ip . ' 成功');
  63 + } else {
  64 + $this->output('修改主机记录 ' . $record_rr . ' 的值为 ' . $target_ip . ' 失败');
  65 + }
  66 + }
  67 + }
  68 + } catch (\Exception $e) {
  69 + $this->output($e->getMessage());
  70 + }
  71 + }
  72 +
  73 + /**
  74 + * 输出处理日志
  75 + * @param $message
  76 + */
  77 + public function output($message)
  78 + {
  79 + echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
  80 + }
  81 +}
@@ -47,17 +47,6 @@ class EmergencyRenewSite extends Command @@ -47,17 +47,6 @@ class EmergencyRenewSite extends Command
47 continue; 47 continue;
48 } 48 }
49 49
50 - //获取站点其他域名  
51 - $other_domain = [];  
52 - if (strpos($domain_info['domain'], 'www.') === 0) {  
53 - $other_domain[] = str_replace('www', '*', $domain_info['domain']);  
54 -  
55 - $top_domain = str_replace('www.', '', $domain_info['domain']);  
56 - if ($this->check_cname($top_domain, $target_server)) {  
57 - $other_domain[] = $top_domain;  
58 - }  
59 - }  
60 -  
61 //创建目标服务器建站任务 50 //创建目标服务器建站任务
62 $map_create = [ 51 $map_create = [
63 'type' => DomainCreateTask::TYPE_MAIN, 52 'type' => DomainCreateTask::TYPE_MAIN,
@@ -68,7 +57,6 @@ class EmergencyRenewSite extends Command @@ -68,7 +57,6 @@ class EmergencyRenewSite extends Command
68 ]; 57 ];
69 $task_info = $create_model->read($map_create, ['id']); 58 $task_info = $create_model->read($map_create, ['id']);
70 if (!$task_info) { 59 if (!$task_info) {
71 - $other_domain && $map_create['other_domain'] = json_encode($other_domain);  
72 $create_model->add($map_create); 60 $create_model->add($map_create);
73 } 61 }
74 62
@@ -275,8 +275,12 @@ class VideoTask extends Command @@ -275,8 +275,12 @@ class VideoTask extends Command
275 } 275 }
276 }else{ 276 }else{
277 $product_all_id = Product::where('thumb','!=',null)->where("status",Product::STATUS_ON)->inRandomOrder()->take(20)->pluck('id')->toArray(); 277 $product_all_id = Product::where('thumb','!=',null)->where("status",Product::STATUS_ON)->inRandomOrder()->take(20)->pluck('id')->toArray();
  278 + if(empty($product_all_id)){
  279 + $products = [];
  280 + }else{
278 $products = Product::whereIn("id", $product_all_id)->orderByRaw(DB::raw("FIELD(id, " . implode(',', $product_all_id) . ")"))->get(); 281 $products = Product::whereIn("id", $product_all_id)->orderByRaw(DB::raw("FIELD(id, " . implode(',', $product_all_id) . ")"))->get();
279 } 282 }
  283 + }
280 $data = []; 284 $data = [];
281 if (!empty($products)){ 285 if (!empty($products)){
282 foreach ($products as $item){ 286 foreach ($products as $item){
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :CountProject.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2024/9/26 14:19
  8 + */
  9 +
  10 +namespace App\Console\Commands\Project;
  11 +
  12 +use App\Models\Project\Project;
  13 +use Illuminate\Console\Command;
  14 +use PhpOffice\PhpSpreadsheet\Spreadsheet;
  15 +use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  16 +
  17 +class countProject extends Command
  18 +{
  19 + /**
  20 + * The name and signature of the console command.
  21 + *
  22 + * @var string
  23 + */
  24 + protected $signature = 'month_count_project';
  25 +
  26 + /**
  27 + * The console command description.
  28 + *
  29 + * @var string
  30 + */
  31 + protected $description = '项目数据统计生成文件';
  32 +
  33 + public function handle(){
  34 + $start = '2023-10';
  35 + $end = '2024-09';
  36 + $data = $this->exportDataProject($start,$end);
  37 + $result = $this->exportData($data);
  38 + echo date('Y-m-d H:i:s') . ' ' . json_encode($result) . PHP_EOL;
  39 + return $result;
  40 +
  41 + }
  42 +
  43 + public function exportData($data){
  44 + // 创建一个新的 Excel 电子表格实例
  45 + $spreadsheet = new Spreadsheet();
  46 + $sheet = $spreadsheet->getActiveSheet();
  47 + // 添加表头
  48 + $sheet->setCellValue('A1', '月份');
  49 + $sheet->setCellValue('B1', '开始时间');
  50 + $sheet->setCellValue('C1', '结束时间');
  51 + $sheet->setCellValue('D1', '创建项目数量');
  52 + $sheet->setCellValue('E1', '上线项目数量');
  53 + $sheet->setCellValue('F1', '上线比例');
  54 + $sheet->setCellValue('G1', '项目总数');
  55 + $sheet->setCellValue('H1', '上线项目总数');
  56 + $sheet->setCellValue('I1', '推广项目总数');
  57 + $sheet->setCellValue('J1', '建站项目总数');
  58 + $sheet->setCellValue('K1', '未上线项目数量');
  59 + $sheet->setCellValue('L1', '删除项目数量');
  60 + $sheet->setCellValue('M1', '上线最快时间');
  61 + $sheet->setCellValue('N1', '上线最慢');
  62 + $sheet->setCellValue('O1', '平均上线天数');
  63 + $rowCount = 2;
  64 +// $allData = $this->countAll();
  65 + foreach ($data as $v) {
  66 + $sheet->setCellValue('A' . $rowCount, $v['month']);
  67 + $sheet->setCellValue('B' . $rowCount, $v['start']);
  68 + $sheet->setCellValue('C' . $rowCount, $v['end']);
  69 + $sheet->setCellValue('D' . $rowCount, $v['month_create_project_count']);
  70 + $sheet->setCellValue('E' . $rowCount, $v['month_project_go_online_count']);
  71 + $sheet->setCellValue('F' . $rowCount, $v['month_project_online_rate']);
  72 + $sheet->setCellValue('G' . $rowCount, $v['count']);
  73 + $sheet->setCellValue('H' . $rowCount, $v['go_online_count']);
  74 + $sheet->setCellValue('I' . $rowCount, $v['promotion_web_count']);
  75 + $sheet->setCellValue('J' . $rowCount, $v['create_web_count']);
  76 + $sheet->setCellValue('K' . $rowCount, $v['no_go_oline_count']);
  77 + $sheet->setCellValue('L' . $rowCount, $v['delete_project_count']);
  78 + $sheet->setCellValue('M' . $rowCount, $v['min_project_count']);
  79 + $sheet->setCellValue('N' . $rowCount, $v['max_project_count']);
  80 + $sheet->setCellValue('O' . $rowCount, $v['average']);
  81 + $rowCount++;
  82 + }
  83 + // 创建一个新的 Excel Writer 对象
  84 + $writer = new Xlsx($spreadsheet);
  85 + $filename = time().'.xlsx';
  86 + // 设置导出文件的保存路径和文件名
  87 + $filePath = public_path('upload/excel/'.$filename);
  88 + // 导出 Excel 文件
  89 + $writer->save($filePath);
  90 + // 返回导出文件的响应
  91 + return ['file_link'=>url('upload/excel/'.$filename)];
  92 + }
  93 + /**
  94 + * @remark :获取所有月份
  95 + * @name :getMonthsBetween
  96 + * @author :lyh
  97 + * @method :post
  98 + * @time :2024/9/26 10:43
  99 + */
  100 + public function getMonthsBetween($startDate, $endDate)
  101 + {
  102 + // 创建 DateTime 对象
  103 + $start = new \DateTime($startDate);
  104 + $end = new \DateTime($endDate);
  105 + // 确保结束时间是该月份的最后一天,以包含结束月份
  106 + $end->modify('first day of next month');
  107 + // 用于存储所有月份
  108 + $months = [];
  109 + // 循环遍历每个月
  110 + while ($start < $end) {
  111 + $months[] = $start->format('Y-m'); // 格式化成 YYYY-MM
  112 + $start->modify('+1 month'); // 增加一个月
  113 + }
  114 + return $months;
  115 + }
  116 +
  117 + /**
  118 + * @remark :根据时间获取开始时间+结束时间
  119 + * @name :getStartAndEndOfMonth
  120 + * @author :lyh
  121 + * @method :post
  122 + * @time :2024/9/26 10:44
  123 + */
  124 + public function getStartAndEndOfMonth($month) {
  125 + // 创建指定月份的 DateTime 对象
  126 + $start = new \DateTime($month . '-01'); // 月份的第一天
  127 + // 复制开始日期并获取该月的最后一天
  128 + $end = clone $start;
  129 + $end->modify('last day of this month'); // 修改为该月的最后一天
  130 + // 格式化成 'Y-m-d H:i:s'
  131 + $startTime = $start->format('Y-m-d 00:00:00'); // 开始时间,精确到天的开始
  132 + $endTime = $end->format('Y-m-d 23:59:59'); // 结束时间,精确到天的结束
  133 + return [
  134 + 'start' => $startTime,
  135 + 'end' => $endTime,
  136 + ];
  137 + }
  138 +
  139 + /**
  140 + * @remark :导出数据
  141 + * @name :exportData
  142 + * @author :lyh
  143 + * @method :post
  144 + * @time :2023/8/1 16:45
  145 + */
  146 + public function exportDataProject($start_month,$end_month){
  147 + $data = [];
  148 + $monthData = $this->getMonthsBetween($start_month,$end_month);
  149 + $projectModel = new Project();
  150 + foreach ($monthData as $v){
  151 + $data[$v]['month'] = $v;
  152 + $timeArr = $this->getStartAndEndOfMonth($v);
  153 + $start_time = $timeArr['start'];
  154 + $end_time = $timeArr['end'];
  155 + $data[$v]['start'] = $start_time;
  156 + $data[$v]['end'] = $end_time;
  157 + //每月创建项目数据
  158 + $data[$v]['month_create_project_count'] = $projectModel->counts(['created_at'=>['between',[$start_time,$end_time]],'deleted_at'=>0]);//每月创建项目数量
  159 + $data[$v]['month_project_go_online_count'] = $projectModel->counts(['uptime'=>['between',[$start_time,$end_time]],'deleted_at'=>0]);//当月上线项目数量
  160 + $data[$v]['month_project_online_rate'] = 0;
  161 + if($data[$v]['month_create_project_count'] != 0){
  162 + $data[$v]['month_project_online_rate'] = round($data[$v]['month_project_go_online_count'] / $data[$v]['month_create_project_count'],2);//比例
  163 + }
  164 + $data[$v]['count'] = $projectModel->counts(['delete_status'=>0]);//所有项目总数
  165 + $data[$v]['go_online_count'] = $projectModel->counts(['uptime'=>['!=',null],'delete_status'=>0]);//上线项目总数
  166 + $data[$v]['promotion_web_count'] = $projectModel->counts(['type'=>3,'delete_status'=>0,'created_at'=>['between',[$start_time,$end_time]]]);//推广项目总数
  167 + $data[$v]['create_web_count'] = $projectModel->counts(['type'=>2,'delete_status'=>0,'created_at'=>['between',[$start_time,$end_time]]]);//建站项目总数
  168 + $data[$v]['no_go_oline_count'] = $projectModel->counts(['uptime'=>null,'delete_status'=>0,'created_at'=>['between',[$start_time,$end_time]]]);//未上线项目数量
  169 + $data[$v]['delete_project_count'] = $projectModel->counts(['delete_status'=>1,'created_at'=>['between',[$start_time,$end_time]]]);//删除
  170 + $min_info = $projectModel->select('*')
  171 + ->selectRaw('DATEDIFF(STR_TO_DATE(uptime, "%Y-%m-%d"), STR_TO_DATE(created_at, "%Y-%m-%d")) AS diff')
  172 + ->whereNotNull('uptime') // 确保 uptime 字段不为空
  173 + ->where('created_at','<=',$end_time)
  174 + ->whereBetween('created_at', [$start_time,$end_time])
  175 + ->orderByRaw('diff ASC')
  176 + ->first();
  177 + $data[$v]['min_project_count'] = $min_info['diff'];
  178 + $max_info = $projectModel->select('*')
  179 + ->selectRaw('DATEDIFF(STR_TO_DATE(uptime, "%Y-%m-%d"), STR_TO_DATE(created_at, "%Y-%m-%d")) AS diff')
  180 + ->whereNotNull('uptime') // 确保 uptime 字段不为空
  181 + ->whereBetween('created_at', [$start_time,$end_time])
  182 + ->orderByRaw('diff DESC')
  183 + ->first();
  184 + $data[$v]['max_project_count'] = $max_info['diff'];
  185 + $data[$v]['average'] = ceil(($max_info['diff'] + $min_info['diff']) / 2);
  186 + }
  187 + return $data;
  188 + }
  189 +
  190 + /**
  191 + * @remark :所有项目总数
  192 + * @name :countAll
  193 + * @author :lyh
  194 + * @method :post
  195 + * @time :2024/9/26 15:11
  196 + */
  197 + public function countAll(){
  198 + $projectModel = new Project();
  199 + $data['count'] = $projectModel->counts(['deleted_at'=>0]);//所有项目总数
  200 + $data['go_online_count'] = $projectModel->counts(['uptime'=>['!=',null],'delete_status'=>0]);//上线项目总数
  201 + $data['promotion_web_count'] = $projectModel->counts(['type'=>3,'delete_status'=>0]);//推广项目总数
  202 + $data['create_web_count'] = $projectModel->counts(['type'=>2,'delete_status'=>0]);//建站项目总数
  203 + $data['no_go_oline_count'] = $projectModel->counts(['uptime'=>null,'delete_status'=>0]);//未上线项目数量
  204 + $data['delete_project_count'] = $projectModel->counts(['delete_status'=>1]);//删除项目数量
  205 + $min_info = $projectModel->select('*')
  206 + ->selectRaw('DATEDIFF(STR_TO_DATE(uptime, "%Y-%m-%d"), STR_TO_DATE(created_at, "%Y-%m-%d")) AS diff')
  207 + ->whereNotNull('uptime') // 确保 uptime 字段不为空
  208 + ->orderByRaw('diff ASC')
  209 + ->first();
  210 + $data['min_project_count'] = $min_info['diff'];
  211 + $max_info = $projectModel->select('*')
  212 + ->selectRaw('DATEDIFF(STR_TO_DATE(uptime, "%Y-%m-%d"), STR_TO_DATE(created_at, "%Y-%m-%d")) AS diff')
  213 + ->whereNotNull('uptime') // 确保 uptime 字段不为空
  214 + ->orderByRaw('diff DESC')
  215 + ->first();
  216 + $data['max_project_count'] = $max_info['diff'];
  217 + $data['average'] = ceil(($max_info['diff'] + $min_info['diff']) / 2);
  218 + return $data;
  219 + }
  220 +}
@@ -69,7 +69,7 @@ class ReplaceHtml extends Command @@ -69,7 +69,7 @@ class ReplaceHtml extends Command
69 foreach ($replaceHtmlList as $v){ 69 foreach ($replaceHtmlList as $v){
70 ProjectServer::useProject($v['project_id']); 70 ProjectServer::useProject($v['project_id']);
71 echo '开始,任务id:'.$v['id'].PHP_EOL; 71 echo '开始,任务id:'.$v['id'].PHP_EOL;
72 - if($v['source'] == 9){//单页面 72 + if(($v['source'] == 9) && ($v['is_custom'] == 0)){//单页面
73 $count = $this->createReplacePageHtmlLog($v); 73 $count = $this->createReplacePageHtmlLog($v);
74 }else{ 74 }else{
75 $count = $this->createReplaceHtmlLog($v); 75 $count = $this->createReplaceHtmlLog($v);
@@ -334,7 +334,7 @@ class ReplaceHtml extends Command @@ -334,7 +334,7 @@ class ReplaceHtml extends Command
334 } 334 }
335 if($is_list == BTemplate::IS_LIST){ 335 if($is_list == BTemplate::IS_LIST){
336 $categoryModel = new CustomModuleCategory(); 336 $categoryModel = new CustomModuleCategory();
337 - $cateInfo = $categoryModel->read(['id'=>$source_id],['id','name']); 337 + $cateInfo = $categoryModel->read(['id'=>$source_id],['id','name','route']);
338 if($cateInfo === false){ 338 if($cateInfo === false){
339 return false; 339 return false;
340 } 340 }
@@ -342,7 +342,7 @@ class ReplaceHtml extends Command @@ -342,7 +342,7 @@ class ReplaceHtml extends Command
342 $route = $cateInfo['route']; 342 $route = $cateInfo['route'];
343 }else{ 343 }else{
344 $contentModel = new CustomModuleContent(); 344 $contentModel = new CustomModuleContent();
345 - $contentInfo = $contentModel->read(['id'=>$source_id],['id','name']); 345 + $contentInfo = $contentModel->read(['id'=>$source_id],['id','name','route']);
346 if($contentInfo === false){ 346 if($contentInfo === false){
347 return false; 347 return false;
348 } 348 }
@@ -33,30 +33,26 @@ class SyncImage extends Command @@ -33,30 +33,26 @@ class SyncImage extends Command
33 33
34 34
35 // public function handle(){ 35 // public function handle(){
36 -// $str = $this->getProjectConfig(501); 36 +// $str = $this->getProjectConfig(1808);
37 // $imageModel = new Image(); 37 // $imageModel = new Image();
38 -// $lists = $imageModel->list(['project_id'=>501]); 38 +// $str_image = '/upload/p/1808/image_product/2024-09/ppp.png,/upload/p/1808/image_product/2024-09/86e4866b-7432-40c1-8c06-d335cd736e29.png,/upload/p/1808/image_product/2024-09/7fd109cc-56f4-457c-a9c4-c3fa8d8195b2.png,/upload/p/1808/image_product/2024-09/1.png,/upload/p/1808/image_product/2024-08/bxb12501-3-1.png,/upload/p/1808/image_product/2024-08/bxa10801-3-1.png,/upload/p/1808/image_product/2024-08/bxa007-3-1.png,/upload/p/1808/image_product/2024-08/auto-parts-rectifier-bxf1070-for-alternator-1-1.png,/upload/p/1808/image_product/2024-08/auto-parts-rectifier-bxd1102-for-alternator-2-1.png,/upload/p/1808/image_product/2024-08/11407-3-1.png,/upload/p/1808/image_product/2024-07/gfjty.jpg,/upload/p/1808/image_product/2024-07/bxn11508-g1-2.png,/upload/p/1808/image_product/2024-07/bxn11508-g1-1.png,/upload/p/1808/image_product/2024-07/bxb12501-2.png,/upload/p/1808/image_product/2024-07/bxb12501-1.png,/upload/p/1808/image_product/2024-07/bxb1209-2.png,/upload/p/1808/image_product/2024-07/bxb1209-1.png,/upload/p/1808/image_product/2024-07/bxa10801-2.png,/upload/p/1808/image_product/2024-07/bxa10801-1.png,/upload/p/1808/image_product/2024-07/bxa007-2.png,/upload/p/1808/image_product/2024-07/bxa007-1.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxf6102-for-alternator-2.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxf1070-for-alternator-3.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxf1070-for-alternator-2.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxd9410-for-alternator-1.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxd1102-for-alternator-3.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxd1102-for-alternator-1.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxb12807-for-alternator-2.png,/upload/p/1808/image_product/2024-07/auto-parts-rectifier-bxb12807-for-alternator-1.png,/upload/p/1808/image_product/2024-07/11407-2.png,/upload/p/1808/image_product/2024-07/11407-1.png';
  39 +// $lists = explode(',',$str_image);
39 // $domain = 'http://globalso-v6-1309677403.cos.ap-hongkong.myqcloud.com';//cos域名 40 // $domain = 'http://globalso-v6-1309677403.cos.ap-hongkong.myqcloud.com';//cos域名
40 -// foreach ($lists as $k => $v){  
41 -// if($v['path'] == '/upload/p/501/image_product/2024-09/6569ac3a212aa39368.png'){  
42 -// continue;  
43 -// }  
44 -// $url = $domain . $v['path'].'?'.$str;  
45 -// echo date('Y-m-d H:i:s') . '水印路径:'. $url .',主键id:'. $v['id'] . PHP_EOL;  
46 -// $this->coverOriginalImage($url,$v['path']); 41 +// foreach ($lists as $v){
  42 +// $url = $domain . $v.'?'.$str;
  43 +// echo date('Y-m-d H:i:s') . '水印路径:'. $url . PHP_EOL;
  44 +// $cdu_url = $this->coverOriginalImage($url,$v);
  45 +// echo date('Y-m-d H:i:s') . '返回的url:'. $cdu_url . PHP_EOL;
47 // } 46 // }
48 // return true; 47 // return true;
49 // } 48 // }
50 49
51 public function handle(){ 50 public function handle(){
52 $data = []; 51 $data = [];
53 - $domain = 'https://ecdn6-nc.globalso.com/'; 52 + $domain = 'https://ecdn6.globalso.com/';
54 $imageModel = new Image(); 53 $imageModel = new Image();
55 - $lists = $imageModel->list(['project_id'=>501]); 54 + $lists = $imageModel->list(['project_id'=>1808]);
56 foreach ($lists as $k => $v){ 55 foreach ($lists as $k => $v){
57 - if($v['path'] == '/upload/p/501/image_product/2024-09/6569ac3a212aa39368.png'){  
58 - continue;  
59 - }  
60 $url = $domain . $v['path']; 56 $url = $domain . $v['path'];
61 echo date('Y-m-d H:i:s') . '刷新路径:'. $url .',主键id:'. $v['id'] . PHP_EOL; 57 echo date('Y-m-d H:i:s') . '刷新路径:'. $url .',主键id:'. $v['id'] . PHP_EOL;
62 $data[] = $url; 58 $data[] = $url;
@@ -8,7 +8,9 @@ use App\Models\Devops\ServerConfig; @@ -8,7 +8,9 @@ use App\Models\Devops\ServerConfig;
8 use App\Models\Devops\ServersIp; 8 use App\Models\Devops\ServersIp;
9 use App\Models\Domain\DomainInfo; 9 use App\Models\Domain\DomainInfo;
10 use App\Models\Project\Project; 10 use App\Models\Project\Project;
  11 +use App\Services\BatchExportService;
11 use Illuminate\Console\Command; 12 use Illuminate\Console\Command;
  13 +use Symfony\Component\Process\Process;
12 14
13 class Temp extends Command 15 class Temp extends Command
14 { 16 {
@@ -26,8 +28,124 @@ class Temp extends Command @@ -26,8 +28,124 @@ class Temp extends Command
26 */ 28 */
27 protected $description = '临时脚本'; 29 protected $description = '临时脚本';
28 30
  31 + /**
  32 + * 获取指定服务器所有项目
  33 + * @author Akun
  34 + * @date 2024/09/30 17:01
  35 + */
29 public function handle() 36 public function handle()
30 { 37 {
  38 + $server_id = 1;
  39 +
  40 + $server_ip_model = new ServersIp();
  41 +
  42 + $server_ip_ids = $server_ip_model->where('servers_id', $server_id)->get()->pluck('id')->toArray();
  43 +
  44 + $project_list = Project::select(['id', 'serve_id', 'title'])->whereIn('serve_id', $server_ip_ids)->get();
  45 +
  46 + $domain_model = new DomainInfo();
  47 + $data = [];
  48 + foreach ($project_list as $value) {
  49 + $domain_info = $domain_model->read(['project_id' => $value->id, 'status' => 1], ['id', 'domain']);
  50 + if (!$domain_info) {
  51 + //过滤未绑定正式域名的项目
  52 + continue;
  53 + }
  54 + $domain = $domain_info['domain'];
  55 +
  56 + $data[] = [
  57 + $value->id,
  58 + $value->title,
  59 + $domain
  60 + ];
  61 + }
  62 + $map = ['项目id', '名称', '域名'];
  63 + if ($data) {
  64 + $table = new BatchExportService("240云服务器项目");
  65 + $file = $table->head($map)->data($data)->save();
  66 + if (!$file) {
  67 + $this->output('文件生成失败,请重试');
  68 + } else {
  69 + $this->output('export success');
  70 + }
  71 + } else {
  72 + $this->output('no data');
  73 + }
  74 + }
  75 +
  76 +
  77 + /**
  78 + * 检查不在所属服务器解析上的域名
  79 + * @author Akun
  80 + * @date 2024/09/26 10:48
  81 + */
  82 + public function handle1()
  83 + {
  84 + $server_id = 14;
  85 +
  86 + $server_ip_model = new ServersIp();
  87 +
  88 + $server_ip_ids = $server_ip_model->where('servers_id', $server_id)->get()->pluck('id')->toArray();
  89 +
  90 + $project_list = Project::select(['id', 'serve_id', 'title'])->whereIn('serve_id', $server_ip_ids)->get();
  91 +
  92 + $domain_model = new DomainInfo();
  93 + $data = [];
  94 + foreach ($project_list as $value) {
  95 + $domain_info = $domain_model->read(['project_id' => $value->id, 'status' => 1], ['id', 'domain']);
  96 + if (!$domain_info) {
  97 + //过滤未绑定正式域名的项目
  98 + continue;
  99 + }
  100 + $domain = $domain_info['domain'];
  101 +
  102 + $check = $this->check_cname($domain);
  103 + foreach ($check as $item) {
  104 + if (strpos($item, 'Address:') !== false) {
  105 + $ip = trim(str_replace('Address:', '', $item));
  106 + if (strpos($ip, '#') === false) {
  107 + $ip_info = $server_ip_model->read(['ip' => $ip]);
  108 + if ($ip_info === false || $ip_info['servers_id'] != $server_id) {
  109 + $data[] = [
  110 + $value->id,
  111 + $value->title,
  112 + $domain,
  113 + $ip,
  114 + $ip_info ? $ip_info['servers_id'] : '',
  115 + ];
  116 + }
  117 + }
  118 + }
  119 + }
  120 + }
  121 + $map = ['项目id', '名称', '域名', 'IP', '服务器ID',];
  122 + if ($data) {
  123 + $table = new BatchExportService("美服2项目解析未在当前服务器项目");
  124 + $file = $table->head($map)->data($data)->save();
  125 + if (!$file) {
  126 + $this->output('文件生成失败,请重试');
  127 + } else {
  128 + $this->output('export success');
  129 + }
  130 + } else {
  131 + $this->output('no data');
  132 + }
  133 + }
  134 +
  135 + public function check_cname($domain)
  136 + {
  137 + $process = new Process(['nslookup', '-qt=a', $domain]);
  138 + $process->run();
  139 + return explode(PHP_EOL, $process->getOutput());
  140 + }
  141 +
  142 + /**
  143 + * 创建所有amp站页面生成任务
  144 + * @author Akun
  145 + * @date 2024/09/26 10:48
  146 + */
  147 + public function handle2()
  148 + {
31 $notify_model = new Notify(); 149 $notify_model = new Notify();
32 $project_model = new Project(); 150 $project_model = new Project();
33 $serve_ip_model = new ServersIp(); 151 $serve_ip_model = new ServersIp();
@@ -56,7 +56,7 @@ class UpdateRoute extends Command @@ -56,7 +56,7 @@ class UpdateRoute extends Command
56 */ 56 */
57 public function handle(){ 57 public function handle(){
58 $projectModel = new Project(); 58 $projectModel = new Project();
59 - $list = $projectModel->list(['id'=>['in',[2350]]]); 59 + $list = $projectModel->list(['id'=>['in',[1646]]]);
60 $data = []; 60 $data = [];
61 foreach ($list as $v){ 61 foreach ($list as $v){
62 echo date('Y-m-d H:i:s') . 'project_id:'.$v['id'] . PHP_EOL; 62 echo date('Y-m-d H:i:s') . 'project_id:'.$v['id'] . PHP_EOL;
@@ -222,18 +222,18 @@ class UpdateRoute extends Command @@ -222,18 +222,18 @@ class UpdateRoute extends Command
222 if(!empty($lists)){ 222 if(!empty($lists)){
223 foreach ($lists as $v){ 223 foreach ($lists as $v){
224 if(!empty($v['route'])){ 224 if(!empty($v['route'])){
225 -// $tag = "-product";  
226 -// if (!(substr($v['route'], -strlen($tag)) === $tag)) {  
227 -// echo date('Y-m-d H:i:s') . '拼接'.$tag . PHP_EOL;  
228 -// $route = $v['route'].$tag;  
229 -// // 如果不是以 '-product' 结尾,则拼接上 '-product'  
230 -// $route = RouteMap::setRoute($route, RouteMap::SOURCE_PRODUCT, $v['id'], $v['project_id']);  
231 -// $productModel->edit(['route'=>$route],['id'=>$v['id']]);  
232 -// }else{ 225 + $tag = "-product";
  226 + if (!(substr($v['route'], -strlen($tag)) === $tag)) {
  227 + echo date('Y-m-d H:i:s') . '拼接'.$tag . PHP_EOL;
  228 + $route = $v['route'].$tag;
  229 + // 如果不是以 '-product' 结尾,则拼接上 '-product'
  230 + $route = RouteMap::setRoute($route, RouteMap::SOURCE_PRODUCT, $v['id'], $v['project_id']);
  231 + $productModel->edit(['route'=>$route],['id'=>$v['id']]);
  232 + }else{
233 echo date('Y-m-d H:i:s') . 'id :'.$v['id'] . PHP_EOL; 233 echo date('Y-m-d H:i:s') . 'id :'.$v['id'] . PHP_EOL;
234 $route = RouteMap::setRoute($v['title'], RouteMap::SOURCE_PRODUCT, $v['id'], $v['project_id']); 234 $route = RouteMap::setRoute($v['title'], RouteMap::SOURCE_PRODUCT, $v['id'], $v['project_id']);
235 $productModel->edit(['route'=>$route],['id'=>$v['id']]); 235 $productModel->edit(['route'=>$route],['id'=>$v['id']]);
236 -// } 236 + }
237 continue; 237 continue;
238 }else{ 238 }else{
239 echo date('Y-m-d H:i:s') . 'id :'.$v['id'] . PHP_EOL; 239 echo date('Y-m-d H:i:s') . 'id :'.$v['id'] . PHP_EOL;
@@ -135,6 +135,9 @@ class Common @@ -135,6 +135,9 @@ class Common
135 if(isset($cache) && ($cache['is_cache'] == true)){ 135 if(isset($cache) && ($cache['is_cache'] == true)){
136 if(is_array($id)){ 136 if(is_array($id)){
137 foreach ($id as $v){ 137 foreach ($id as $v){
  138 + if(is_array($v)){
  139 + continue;
  140 + }
138 $key = 'cache_'.$table.'_'.$v.'_type'; 141 $key = 'cache_'.$table.'_'.$v.'_type';
139 Cache::store('file')->pull($key); 142 Cache::store('file')->pull($key);
140 } 143 }
@@ -8,12 +8,15 @@ @@ -8,12 +8,15 @@
8 namespace App\Http\Controllers\Api; 8 namespace App\Http\Controllers\Api;
9 9
10 use App\Models\Com\KeywordVideoTaskLog; 10 use App\Models\Com\KeywordVideoTaskLog;
  11 +use App\Models\Domain\DomainInfo;
  12 +use App\Models\Domain\DomainRedirectTask;
11 use App\Models\Product\Keyword; 13 use App\Models\Product\Keyword;
12 use App\Models\Visit\SyncSubmitTask; 14 use App\Models\Visit\SyncSubmitTask;
13 use App\Models\Visit\Visit; 15 use App\Models\Visit\Visit;
14 use App\Services\ProjectServer; 16 use App\Services\ProjectServer;
15 use Illuminate\Http\Request; 17 use Illuminate\Http\Request;
16 use Illuminate\Support\Facades\DB; 18 use Illuminate\Support\Facades\DB;
  19 +use Symfony\Component\Process\Process;
17 20
18 /** 21 /**
19 * Class NoticeController 22 * Class NoticeController
@@ -105,4 +108,79 @@ class NoticeController extends BaseController @@ -105,4 +108,79 @@ class NoticeController extends BaseController
105 DB::disconnect('custom_mysql'); 108 DB::disconnect('custom_mysql');
106 return 200; 109 return 200;
107 } 110 }
  111 +
  112 + /**
  113 + * 创建301跳转任务
  114 + * @param Request $request
  115 + * @return false|string
  116 + * @author Akun
  117 + * @date 2024/10/08 15:24
  118 + */
  119 + public function addRedirect(Request $request)
  120 + {
  121 + $origin_domain = $request->input('origin_domain', '');
  122 + $other_domain = $request->input('other_domain', []);
  123 + $target_domain = $request->input('target_domain', '');
  124 +
  125 + if ($other_domain && !is_array($other_domain)) {
  126 + return $this->error('other_domain参数必须为数组');
  127 + }
  128 +
  129 + if (empty($origin_domain)) {
  130 + return $this->error('origin_domain参数不能为空');
  131 + }
  132 +
  133 + if (empty($target_domain)) {
  134 + return $this->error('target_domain参数不能为空');
  135 + }
  136 +
  137 + if(!$this->check_a($origin_domain,DomainInfo::SERVER_IP_301)){
  138 + return $this->error($origin_domain . ' 未解析至 ' . DomainInfo::SERVER_IP_301);
  139 + }
  140 +
  141 + if($other_domain){
  142 + foreach ($other_domain as $ov) {
  143 + if (!$this->check_a($ov, DomainInfo::SERVER_IP_301)) {
  144 + return $this->error($ov . ' 未解析至 ' . DomainInfo::SERVER_IP_301);
  145 + }
  146 + }
  147 + }
  148 +
  149 + //新增重定向任务
  150 + $redirect_model = new DomainRedirectTask();
  151 + $task_redirect_info = $redirect_model->read(['origin_domain'=>$origin_domain]);
  152 + if(!$task_redirect_info){
  153 + $redirect_model->add([
  154 + 'origin_domain'=> $origin_domain,
  155 + 'other_domain' => json_encode($other_domain),
  156 + 'target_domain' => $target_domain
  157 + ]);
  158 + }
  159 +
  160 + return $this->success();
  161 + }
  162 +
  163 + /**
  164 + * 验证是否A记录解析到目标服务器
  165 + * @param $domain
  166 + * @param $ip
  167 + * @return bool
  168 + * @author Akun
  169 + * @date 2024/09/19 11:14
  170 + */
  171 + public function check_a($domain, $ip)
  172 + {
  173 + $process = new Process(['nslookup', '-qt=a', $domain]);
  174 + $process->run();
  175 + $output = explode(PHP_EOL, $process->getOutput());
  176 + foreach ($output as $line) {
  177 + if ($line) {
  178 + $checkA = strpos($line, $ip) !== false;
  179 + if ($checkA) {
  180 + return $domain;
  181 + }
  182 + }
  183 + }
  184 + return false;
  185 + }
108 } 186 }
@@ -21,6 +21,8 @@ use Illuminate\Support\Facades\Cache; @@ -21,6 +21,8 @@ use Illuminate\Support\Facades\Cache;
21 use Illuminate\Support\Facades\DB; 21 use Illuminate\Support\Facades\DB;
22 use Illuminate\Support\Facades\Hash; 22 use Illuminate\Support\Facades\Hash;
23 use Illuminate\Support\Facades\Log; 23 use Illuminate\Support\Facades\Log;
  24 +use PhpOffice\PhpSpreadsheet\Spreadsheet;
  25 +use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
24 26
25 /** 27 /**
26 * Class IndexController 28 * Class IndexController
@@ -167,4 +169,6 @@ class IndexController extends BaseController @@ -167,4 +169,6 @@ class IndexController extends BaseController
167 } 169 }
168 $this->response('success',Code::SUCCESS,['dynamic_password'=>$dynamic_password]); 170 $this->response('success',Code::SUCCESS,['dynamic_password'=>$dynamic_password]);
169 } 171 }
  172 +
  173 +
170 } 174 }
  1 +<?php
  2 +
  3 +namespace App\Http\Controllers\Aside\PackDir;
  4 +
  5 +use App\Enums\Common\Code;
  6 +use App\Http\Controllers\Aside\BaseController;
  7 +use App\Models\Devops\Servers;
  8 +use App\Models\Devops\ServersIp;
  9 +use App\Models\Domain\DomainInfo;
  10 +use App\Models\Manage\Manage;
  11 +use App\Models\PackDir\SitePackTask;
  12 +use App\Models\Project\Project;
  13 +
  14 +class PackDirController extends BaseController
  15 +{
  16 + /**
  17 + * 获取打包静态页面任务列表
  18 + * @author Akun
  19 + * @date 2024/10/08 16:12
  20 + */
  21 + public function getTaskLists()
  22 + {
  23 + $autoModule = new SitePackTask();
  24 + $lists = $autoModule->lists($this->map, $this->page, $this->row);
  25 + if (!empty($lists)) {
  26 + $projectModel = new Project();
  27 + $manageModel = new Manage();
  28 + $serverModel = new Servers();
  29 + $domainModel = new DomainInfo();
  30 + foreach ($lists['list'] as $k => $v) {
  31 + $lists['list'][$k]['operator_name'] = $manageModel->getName($v['user_id']);
  32 + $lists['list'][$k]['project_name'] = $projectModel->getProjectName($v['project_id']);
  33 +
  34 + $download_url = '';
  35 + if ($v['status'] == 2) {
  36 + $server_info = $serverModel->read(['id' => $v['server_id']], ['init_domain']);
  37 + $domain_info = $domainModel->read(['project_id' => $v['project_id']], ['domain']);
  38 + if ($server_info && $domain_info) {
  39 + $download_url = 'https://' . $server_info['init_domain'] . '/pack_sites/' . $domain_info['domain'] . '.zip';
  40 + }
  41 + }
  42 + $lists['list'][$k]['download_url'] = $download_url;
  43 + }
  44 + }
  45 +
  46 + $this->response('success', Code::SUCCESS, $lists);
  47 + }
  48 +
  49 + /**
  50 + * 添加静态页面打包任务
  51 + * @throws \App\Exceptions\AsideGlobalException
  52 + * @author Akun
  53 + * @date 2024/10/08 16:39
  54 + */
  55 + public function saveTask()
  56 + {
  57 + $this->request->validate([
  58 + 'project_id' => 'required',
  59 + ], [
  60 + 'project_id.required' => '项目不能为空'
  61 + ]);
  62 +
  63 + $domainModel = new DomainInfo();
  64 + $domain_info = $domainModel->read(['project_id' => $this->param['project_id']], ['domain']);
  65 + if (!$domain_info) {
  66 + $this->fail('项目未上线,无法打包静态页面');
  67 + }
  68 + $projectModel = new Project();
  69 + $project_info = $projectModel->read(['id' => $this->param['project_id']], ['serve_id']);
  70 + if (!$project_info) {
  71 + $this->fail('未查询到项目所属服务器信息');
  72 + }
  73 + $serverIpModel = new ServersIp();
  74 + $server_ip_info = $serverIpModel->read(['id' => $project_info['serve_id']], ['servers_id']);
  75 + if (!$server_ip_info) {
  76 + $this->fail('未查询到项目所属服务器信息');
  77 + }
  78 +
  79 + $data = [
  80 + 'user_id' => $this->uid,
  81 + 'project_id' => $this->param['project_id'],
  82 + 'server_id' => $server_ip_info['servers_id']
  83 + ];
  84 + $model = new SitePackTask();
  85 + $pack_info = $model->read(array_merge($data, ['status' => ['in', [SitePackTask::STATUS_UN, SitePackTask::STATUS_ING]]]));
  86 + if ($pack_info) {
  87 + $this->fail('当前项目已有打包任务进行中,请勿重复提交');
  88 + }
  89 + $model->add($data);
  90 +
  91 + $this->response('success');
  92 + }
  93 +}
@@ -285,7 +285,7 @@ class ProjectController extends BaseController @@ -285,7 +285,7 @@ class ProjectController extends BaseController
285 if($this->map['domain'] == 0){ 285 if($this->map['domain'] == 0){
286 $query = $query->where('gl_project_deploy_optimize.domain',null); 286 $query = $query->where('gl_project_deploy_optimize.domain',null);
287 }else{ 287 }else{
288 - $query = $query->where('gl_project_deploy_optimize.domain',null); 288 + $query = $query->where('gl_project_deploy_optimize.domain','!=',null);
289 } 289 }
290 } 290 }
291 return $query; 291 return $query;
@@ -608,9 +608,6 @@ class ProjectController extends BaseController @@ -608,9 +608,6 @@ class ProjectController extends BaseController
608 */ 608 */
609 public function getManagerList(){ 609 public function getManagerList(){
610 $hrManagerModel = new ManageHr(); 610 $hrManagerModel = new ManageHr();
611 - if(!isset($this->param['name']) || empty($this->param['name'])){  
612 - $this->map['status'] = $hrManagerModel::STATUS_ONE;  
613 - }  
614 if(isset($this->map['entry_position']) && !empty($this->map['entry_position'])){ 611 if(isset($this->map['entry_position']) && !empty($this->map['entry_position'])){
615 $this->map['entry_position'] = ['in',$this->map['entry_position']]; 612 $this->map['entry_position'] = ['in',$this->map['entry_position']];
616 } 613 }
@@ -12,6 +12,8 @@ namespace App\Http\Controllers\Bside\BCom; @@ -12,6 +12,8 @@ namespace App\Http\Controllers\Bside\BCom;
12 use App\Enums\Common\Code; 12 use App\Enums\Common\Code;
13 use App\Http\Controllers\Bside\BaseController; 13 use App\Http\Controllers\Bside\BaseController;
14 use App\Models\Log\OperationHeartbeat; 14 use App\Models\Log\OperationHeartbeat;
  15 +use App\Models\Manage\Manage;
  16 +use App\Models\User\User;
15 17
16 class OperationHeartbeatController extends BaseController 18 class OperationHeartbeatController extends BaseController
17 { 19 {
@@ -36,6 +38,7 @@ class OperationHeartbeatController extends BaseController @@ -36,6 +38,7 @@ class OperationHeartbeatController extends BaseController
36 'is_custom.required' => '是否为扩展模版', 38 'is_custom.required' => '是否为扩展模版',
37 'is_template.required' => '详情页/可视化', 39 'is_template.required' => '详情页/可视化',
38 ]); 40 ]);
  41 +
39 $condition = ['project_id'=>$this->user['project_id'],'source'=>$this->param['source'],'source_id'=>$this->param['source_id'], 42 $condition = ['project_id'=>$this->user['project_id'],'source'=>$this->param['source'],'source_id'=>$this->param['source_id'],
40 'is_list'=>$this->param['is_list'],'is_custom'=>$this->param['is_custom'],'is_template'=>$this->param['is_template']]; 43 'is_list'=>$this->param['is_list'],'is_custom'=>$this->param['is_custom'],'is_template'=>$this->param['is_template']];
41 $operationHeartbeatModel = new OperationHeartbeat(); 44 $operationHeartbeatModel = new OperationHeartbeat();
@@ -44,9 +47,11 @@ class OperationHeartbeatController extends BaseController @@ -44,9 +47,11 @@ class OperationHeartbeatController extends BaseController
44 if($info === false){ 47 if($info === false){
45 $condition['operator_id'] = $this->user['id']; 48 $condition['operator_id'] = $this->user['id'];
46 $condition['project_id'] = $this->user['project_id']; 49 $condition['project_id'] = $this->user['project_id'];
  50 + $condition['ip'] = $this->request->ip();
  51 + $condition['manager_id'] = $this->user['manager_id'] ?? 0;
47 $operationHeartbeatModel->addReturnId($condition); 52 $operationHeartbeatModel->addReturnId($condition);
48 }else{ 53 }else{
49 - $operationHeartbeatModel->edit(['status'=>$condition['status'] ?? 0],['id'=>$info['id']]); 54 + $operationHeartbeatModel->edit(['status'=>$condition['status'] ?? 0,'ip'=>$this->request->ip(),'manager_id'=> $this->user['manager_id'] ?? 0],['id'=>$info['id']]);
50 } 55 }
51 $this->response('success'); 56 $this->response('success');
52 } 57 }
@@ -75,15 +80,33 @@ class OperationHeartbeatController extends BaseController @@ -75,15 +80,33 @@ class OperationHeartbeatController extends BaseController
75 $condition = ['project_id'=>$this->user['project_id'],'source'=>$this->param['source'],'source_id'=>$this->param['source_id'], 80 $condition = ['project_id'=>$this->user['project_id'],'source'=>$this->param['source'],'source_id'=>$this->param['source_id'],
76 'is_list'=>$this->param['is_list'],'is_custom'=>$this->param['is_custom'],'is_template'=>$this->param['is_template']]; 81 'is_list'=>$this->param['is_list'],'is_custom'=>$this->param['is_custom'],'is_template'=>$this->param['is_template']];
77 $operationHeartbeatModel = new OperationHeartbeat(); 82 $operationHeartbeatModel = new OperationHeartbeat();
78 - $info = $operationHeartbeatModel->read($condition,['id','status','updated_at']); 83 + $info = $operationHeartbeatModel->read($condition,['id','status','manager_id','ip','operator_id','updated_at']);
79 if($info === false){ 84 if($info === false){
80 $info = []; 85 $info = [];
81 }else{ 86 }else{
82 - $date_time = strtotime($info['updated_at']) + 7200; 87 + $date_time = strtotime($info['updated_at']) + 120;
83 if($date_time < time()){ 88 if($date_time < time()){
84 - $operationHeartbeatModel->edit(['status'=>0],$condition); 89 + $operationHeartbeatModel->edit(['status'=>0,'ip'=>'127.0.0.1'],$condition);
85 $info['status'] = 0; 90 $info['status'] = 0;
86 } 91 }
  92 + if($info['status'] == 1){
  93 + //当前登录为切入登录
  94 + if(isset($this->user['manager_id']) && !empty($this->user['manager_id'])){
  95 + //上一次验证也是切入登录
  96 + if($info['manager_id'] != 0){
  97 + $managerModel = new Manage();
  98 + $managerInfo = $managerModel->read(['id'=>$info['manager_id']],['name']);
  99 + $info['message'] = '此页面数据已有人在编辑,请勿重复操作!操作人ip:'.$info['ip'].'操作的管理员为:'.$managerInfo['name'];
  100 + }else{
  101 + //账号密码登录
  102 + $userModel = new User();
  103 + $userInfo = $userModel->read(['id'=>$info['operator_id']],['name']);
  104 + $info['message'] = '此页面数据已有人在编辑,请勿重复操作!'.$userInfo['name'].'用户登录在操作。';
  105 + }
  106 + }else{
  107 + $info['message'] = '此页面数据已有人在编辑,请勿重复操作!';
  108 + }
  109 + }
87 } 110 }
88 $this->response('success',Code::SUCCESS,$info); 111 $this->response('success',Code::SUCCESS,$info);
89 } 112 }
@@ -173,16 +173,15 @@ class FileManageController extends BaseController @@ -173,16 +173,15 @@ class FileManageController extends BaseController
173 173
174 public function delete(Request $request){ 174 public function delete(Request $request){
175 $request->validate([ 175 $request->validate([
176 - 'id'=>'required', 176 + 'id'=>'required | array',
177 ],[ 177 ],[
178 'id.required' => 'ID不能为空', 178 'id.required' => 'ID不能为空',
179 ]); 179 ]);
180 - $fileManage = FileManage::find($this->param['id']);  
181 - if(!$fileManage){  
182 - $this->response('数据不存在或者已经删除'); 180 + if(!is_array($this->param['id'])){
  181 + $this->param['id'] = [$this->param['id']];
183 } 182 }
184 - $fileManage->delete();  
185 - 183 + $fileManage = new FileManage();
  184 + $fileManage->del(['id'=>['in',$this->param['id']]]);
186 $this->response('success'); 185 $this->response('success');
187 } 186 }
188 } 187 }
@@ -297,8 +297,7 @@ class LoginController extends BaseController @@ -297,8 +297,7 @@ class LoginController extends BaseController
297 ]; 297 ];
298 } 298 }
299 } 299 }
300 -  
301 - $info = $logic->autologin($data); 300 + $info = $logic->autologin($data,User::LOGIN_OTHER_SOURCE);
302 $this->response('success',Code::SUCCESS,['info'=>$info]); 301 $this->response('success',Code::SUCCESS,['info'=>$info]);
303 } 302 }
304 303
@@ -788,7 +788,7 @@ class ProductController extends BaseController @@ -788,7 +788,7 @@ class ProductController extends BaseController
788 'keyword_id'=>'required|array', 788 'keyword_id'=>'required|array',
789 ],[ 789 ],[
790 'id.required' => '产品ID不能为空', 790 'id.required' => '产品ID不能为空',
791 - 'category_id.required' => '关键词ID不能为空', 791 + 'keyword_id.required' => '关键词ID不能为空',
792 ]); 792 ]);
793 $logic->batchSetKeyword(); 793 $logic->batchSetKeyword();
794 $this->response('success'); 794 $this->response('success');
@@ -69,7 +69,7 @@ class ReplaceHtmlLogic extends BaseLogic @@ -69,7 +69,7 @@ class ReplaceHtmlLogic extends BaseLogic
69 */ 69 */
70 public function getCustomTemplateId($typeInfo,$template_id){ 70 public function getCustomTemplateId($typeInfo,$template_id){
71 $customModuleModel = new CustomModule(); 71 $customModuleModel = new CustomModule();
72 - $moduleInfo = $customModuleModel->read(['id'=>$typeInfo['type']],['list_customized','detail_customized']); 72 + $moduleInfo = $customModuleModel->read(['id'=>$typeInfo['source']],['list_customized','detail_customized']);
73 if($moduleInfo === false){ 73 if($moduleInfo === false){
74 $this->fail('当前扩展模块不存在或已被删除'); 74 $this->fail('当前扩展模块不存在或已被删除');
75 } 75 }
@@ -186,9 +186,9 @@ class InquiryLogic extends BaseLogic @@ -186,9 +186,9 @@ class InquiryLogic extends BaseLogic
186 public function sendMobileVerifyData($phone){ 186 public function sendMobileVerifyData($phone){
187 $phoneDataModel = new PhoneData(); 187 $phoneDataModel = new PhoneData();
188 $num_phone = preg_replace('/\D/', '',$phone) ?? ''; // \D 匹配所有非数字字符 188 $num_phone = preg_replace('/\D/', '',$phone) ?? ''; // \D 匹配所有非数字字符
189 - $info = $phoneDataModel->read(['phone'=>$num_phone]);  
190 - if($info === false){  
191 - $url = 'https://fob.ai.cc/api/mobile_verify_data/'.$phone; 189 + $data = $phoneDataModel->read(['num_phone'=>$num_phone]);
  190 + if($data === false){
  191 + $url = 'https://fob.ai.cc/api/mobile_verify_data/'.$num_phone;
192 $data = http_get($url); 192 $data = http_get($url);
193 if(!empty($data)){ 193 if(!empty($data)){
194 $param = [ 194 $param = [
@@ -350,6 +350,8 @@ class ProductLogic extends BaseLogic @@ -350,6 +350,8 @@ class ProductLogic extends BaseLogic
350 DB::connection('custom_mysql')->beginTransaction(); 350 DB::connection('custom_mysql')->beginTransaction();
351 try { 351 try {
352 $cateRelate = new CategoryRelated(); 352 $cateRelate = new CategoryRelated();
  353 + //删除扩展字段
  354 + $extendInfoModel = new ExtendInfo();
353 foreach ($this->param['ids'] as $id) { 355 foreach ($this->param['ids'] as $id) {
354 $info = $this->model->read(['id'=>$id],['id','status']); 356 $info = $this->model->read(['id'=>$id],['id','status']);
355 if($info['status'] == Product::STATUS_RECYCLE){ 357 if($info['status'] == Product::STATUS_RECYCLE){
@@ -359,6 +361,7 @@ class ProductLogic extends BaseLogic @@ -359,6 +361,7 @@ class ProductLogic extends BaseLogic
359 $this->model->del(['id'=>$id]); 361 $this->model->del(['id'=>$id]);
360 //删除关联表 362 //删除关联表
361 $cateRelate->del(['product_id'=>$id]); 363 $cateRelate->del(['product_id'=>$id]);
  364 + $extendInfoModel->del(['product_id'=>$id]);
362 }else{ 365 }else{
363 //回收站 366 //回收站
364 $this->model->edit(['status'=>Product::STATUS_RECYCLE],['id'=>$id]); 367 $this->model->edit(['status'=>Product::STATUS_RECYCLE],['id'=>$id]);
@@ -107,7 +107,7 @@ class UserLoginLogic @@ -107,7 +107,7 @@ class UserLoginLogic
107 * @method :post 107 * @method :post
108 * @time :2023/9/18 11:00 108 * @time :2023/9/18 11:00
109 */ 109 */
110 - public function autologin($data) 110 + public function autologin($data,$login_source = User::LOGIN_AUTO_SOURCE)
111 { 111 {
112 //项目自动登录 112 //项目自动登录
113 if(isset($data['project_id']) && !empty($data['project_id'])){ 113 if(isset($data['project_id']) && !empty($data['project_id'])){
@@ -120,7 +120,7 @@ class UserLoginLogic @@ -120,7 +120,7 @@ class UserLoginLogic
120 if ($has_user === false) { 120 if ($has_user === false) {
121 $this->fail('该项目未找到注册账号'); 121 $this->fail('该项目未找到注册账号');
122 } 122 }
123 - $info = $this->autoAssembleParam($has_user); 123 + $info = $this->autoAssembleParam($has_user,$login_source);
124 //生成新token 124 //生成新token
125 $token = md5(uniqid().$info['id']); 125 $token = md5(uniqid().$info['id']);
126 //存储缓存 126 //存储缓存
@@ -160,7 +160,7 @@ class UserLoginLogic @@ -160,7 +160,7 @@ class UserLoginLogic
160 * @method :post 160 * @method :post
161 * @time :2023/6/12 15:34 161 * @time :2023/6/12 15:34
162 */ 162 */
163 - public function autoAssembleParam($info){ 163 + public function autoAssembleParam($info,$login_source = User::LOGIN_AUTO_SOURCE){
164 $project = $this->getProjectInfo($info['project_id']); 164 $project = $this->getProjectInfo($info['project_id']);
165 if($project['site_status'] != 0){//关闭站点 165 if($project['site_status'] != 0){//关闭站点
166 $this->fail('当前网站已过期,请联系管理员及时续费。'); 166 $this->fail('当前网站已过期,请联系管理员及时续费。');
@@ -206,7 +206,7 @@ class UserLoginLogic @@ -206,7 +206,7 @@ class UserLoginLogic
206 $is_amp = $amp_info ? $amp_info['amp_status'] : 0; 206 $is_amp = $amp_info ? $amp_info['amp_status'] : 0;
207 } 207 }
208 $info['is_amp'] = $is_amp; 208 $info['is_amp'] = $is_amp;
209 - 209 + $info['login_source'] = $login_source;
210 //保存项目缓存 210 //保存项目缓存
211 Cache::put('user-'.$info['project_id'],$project,12 * 3600); 211 Cache::put('user-'.$info['project_id'],$project,12 * 3600);
212 return $this->success($info); 212 return $this->success($info);
@@ -316,6 +316,7 @@ class UserLoginLogic @@ -316,6 +316,7 @@ class UserLoginLogic
316 $is_amp = $amp_info ? $amp_info['amp_status'] : 0; 316 $is_amp = $amp_info ? $amp_info['amp_status'] : 0;
317 } 317 }
318 $info['is_amp'] = $is_amp; 318 $info['is_amp'] = $is_amp;
  319 + $info['login_source'] = User::LOGIN_PASSWORD_SOURCE;//账号密码登录返回
319 //保存项目缓存 320 //保存项目缓存
320 Cache::put('user-'.$info['project_id'],$project,12 * 3600); 321 Cache::put('user-'.$info['project_id'],$project,12 * 3600);
321 return $this->success($info); 322 return $this->success($info);
@@ -363,7 +364,7 @@ class UserLoginLogic @@ -363,7 +364,7 @@ class UserLoginLogic
363 ]; 364 ];
364 }else { 365 }else {
365 //获取项目详情 366 //获取项目详情
366 - $info = $this->autoAssembleParam($info); 367 + $info = $this->autoAssembleParam($info,User::LOGIN_PASSWORD_SOURCE);
367 if(isset($info['token']) && !empty($info['token'])){ 368 if(isset($info['token']) && !empty($info['token'])){
368 //清除上一次用户缓存 369 //清除上一次用户缓存
369 Cache::pull($info['token']); 370 Cache::pull($info['token']);
@@ -13,7 +13,7 @@ class AutoPullNotify extends Base @@ -13,7 +13,7 @@ class AutoPullNotify extends Base
13 return [ 13 return [
14 1 => '硅谷云服务器', 14 1 => '硅谷云服务器',
15 9 => '硅谷IDC服务器01(6.0美服1)', 15 9 => '硅谷IDC服务器01(6.0美服1)',
16 - 3 => '硅谷IDC服务器02(6.0美服2)', 16 + 14 => '硅谷IDC服务器02(6.0美服2)',
17 2 => '俄罗斯服务器', 17 2 => '俄罗斯服务器',
18 4 => '阿里云深圳服务器', 18 4 => '阿里云深圳服务器',
19 5 => '日本服务器', 19 5 => '日本服务器',
@@ -116,6 +116,17 @@ class Base extends Model @@ -116,6 +116,17 @@ class Base extends Model
116 } 116 }
117 117
118 /** 118 /**
  119 + * @remark :统计数量
  120 + * @name :count
  121 + * @author :lyh
  122 + * @method :post
  123 + * @time :2024/9/26 10:52
  124 + */
  125 + public function counts($condition){
  126 + $condition = $this->filterRequestData($condition);
  127 + return $this->formatQuery($condition)->count();
  128 + }
  129 + /**
119 * @remark :编辑 130 * @remark :编辑
120 * @name :edit 131 * @name :edit
121 * @author :lyh 132 * @author :lyh
  1 +<?php
  2 +
  3 +namespace App\Models\PackDir;
  4 +
  5 +use App\Models\Base;
  6 +
  7 +class SitePackTask extends Base
  8 +{
  9 + protected $table = 'gl_site_pack_task';
  10 +
  11 + const STATUS_UN = 0;
  12 + const STATUS_ING = 1;
  13 + const STATUS_SUC = 2;
  14 + const STATUS_FAL = 3;
  15 + const STATUS_EXP = 4;
  16 +}
@@ -17,6 +17,9 @@ class User extends Base @@ -17,6 +17,9 @@ class User extends Base
17 //自动维护create_at创建时间 updated_at修改时间 17 //自动维护create_at创建时间 updated_at修改时间
18 public $timestamps = true; 18 public $timestamps = true;
19 19
  20 + const LOGIN_AUTO_SOURCE = 1;//自动登录
  21 + const LOGIN_PASSWORD_SOURCE = 2;//账号密码登录
  22 + const LOGIN_OTHER_SOURCE = 3;//其他平台切入
20 /** 23 /**
21 * The attributes that should be cast. 24 * The attributes that should be cast.
22 * 25 *
  1 +<?php
  2 +
  3 +namespace App\Services;
  4 +
  5 +use AlibabaCloud\SDK\Alidns\V20150109\Alidns;
  6 +use AlibabaCloud\SDK\Alidns\V20150109\Models\AddDomainRecordRequest;
  7 +use AlibabaCloud\SDK\Alidns\V20150109\Models\DescribeDomainRecordsRequest;
  8 +use AlibabaCloud\SDK\Alidns\V20150109\Models\UpdateDomainRecordRemarkRequest;
  9 +use AlibabaCloud\SDK\Alidns\V20150109\Models\UpdateDomainRecordRequest;
  10 +use AlibabaCloud\Tea\Utils\Utils;
  11 +use Darabonba\OpenApi\Models\Config;
  12 +
  13 +class AlibabaCloudService
  14 +{
  15 + /**
  16 + * 创建客户端
  17 + * @return Alidns
  18 + * @author Akun
  19 + * @date 2024/09/21 16:16
  20 + */
  21 + public static function createClient()
  22 + {
  23 + $config = new Config([
  24 + 'accessKeyId' => env('ALIBABA_CLOUD_KEY'),
  25 + 'accessKeySecret' => env('ALIBABA_CLOUD_SECRET'),
  26 + ]);
  27 +
  28 + return new Alidns($config);
  29 + }
  30 +
  31 + /**
  32 + * 获取域名解析记录列表
  33 + * @param $domain
  34 + * @param $keyword
  35 + * @param $status
  36 + * @return array
  37 + * @author Akun
  38 + * @date 2024/09/21 17:19
  39 + */
  40 + public static function describeDomainRecords($domain, $keyword, $status = 'Enable')
  41 + {
  42 + $client = self::createClient();
  43 +
  44 + $request = new DescribeDomainRecordsRequest([
  45 + 'domainName' => $domain,
  46 + 'RRKeyWord' => $keyword,
  47 + 'status' => $status,
  48 + ]);
  49 +
  50 + $response = $client->DescribeDomainRecords($request);
  51 +
  52 + return Utils::toArray($response);
  53 + }
  54 +
  55 + /**
  56 + * 添加解析记录
  57 + * @param $domain
  58 + * @param $rr
  59 + * @param $type
  60 + * @param $value
  61 + * @return array
  62 + * @author Akun
  63 + * @date 2024/09/21 17:33
  64 + */
  65 + public static function addDomainRecord($domain, $rr, $type, $value)
  66 + {
  67 + $client = self::createClient();
  68 +
  69 + $request = new AddDomainRecordRequest([
  70 + 'domainName' => $domain,
  71 + 'RR' => $rr,
  72 + 'type' => $type,
  73 + 'value' => $value
  74 + ]);
  75 +
  76 + $response = $client->AddDomainRecord($request);
  77 +
  78 + return Utils::toArray($response);
  79 + }
  80 +
  81 + /**
  82 + * 修改解析记录备注
  83 + * @param $record_id
  84 + * @param $remark
  85 + * @return array
  86 + * @author Akun
  87 + * @date 2024/09/21 17:38
  88 + */
  89 + public static function updateDomainRecordRemark($record_id, $remark)
  90 + {
  91 + $client = self::createClient();
  92 +
  93 + $request = new UpdateDomainRecordRemarkRequest([
  94 + 'recordId' => $record_id,
  95 + 'remark' => $remark,
  96 + ]);
  97 +
  98 + $response = $client->UpdateDomainRecordRemark($request);
  99 +
  100 + return Utils::toArray($response);
  101 + }
  102 +
  103 + /**
  104 + * 修改解析记录详情
  105 + * @param $record_id
  106 + * @param $rr
  107 + * @param $type
  108 + * @param $value
  109 + * @return array
  110 + * @author Akun
  111 + * @date 2024/09/23 10:55
  112 + */
  113 + public static function updateDomainRecord($record_id, $rr, $type, $value)
  114 + {
  115 + $client = self::createClient();
  116 +
  117 + $request = new UpdateDomainRecordRequest([
  118 + 'recordId' => $record_id,
  119 + 'RR' => $rr,
  120 + 'type' => $type,
  121 + 'value' => $value,
  122 + ]);
  123 +
  124 + $response = $client->UpdateDomainRecord($request);
  125 +
  126 + return Utils::toArray($response);
  127 + }
  128 +}
@@ -5,6 +5,8 @@ @@ -5,6 +5,8 @@
5 "keywords": ["framework", "laravel"], 5 "keywords": ["framework", "laravel"],
6 "license": "MIT", 6 "license": "MIT",
7 "require": { 7 "require": {
  8 + "alibabacloud/alidns-20150109": "*",
  9 + "alibabacloud/darabonba-openapi": "^0.2.12",
8 "barryvdh/laravel-dompdf": "^2.0", 10 "barryvdh/laravel-dompdf": "^2.0",
9 "bensampo/laravel-enum": "^4.2", 11 "bensampo/laravel-enum": "^4.2",
10 "beyondcode/laravel-websockets": "^1.14", 12 "beyondcode/laravel-websockets": "^1.14",
@@ -53,4 +53,7 @@ Route::post('selfSiteApi', [\App\Http\Controllers\Api\SelfSiteController::class, @@ -53,4 +53,7 @@ Route::post('selfSiteApi', [\App\Http\Controllers\Api\SelfSiteController::class,
53 Route::post('selfSiteNotify', [\App\Http\Controllers\Api\SelfSiteController::class, 'selfSiteNotify']); 53 Route::post('selfSiteNotify', [\App\Http\Controllers\Api\SelfSiteController::class, 'selfSiteNotify']);
54 Route::post('selfSiteVerify', [\App\Http\Controllers\Api\SelfSiteController::class, 'selfSiteVerify']); 54 Route::post('selfSiteVerify', [\App\Http\Controllers\Api\SelfSiteController::class, 'selfSiteVerify']);
55 55
  56 +//创建301跳转任务
  57 +Route::any('/addRedirect',[\App\Http\Controllers\Api\NoticeController::class,'addRedirect']);
  58 +
56 59
@@ -473,6 +473,13 @@ Route::middleware(['aloginauth'])->group(function () { @@ -473,6 +473,13 @@ Route::middleware(['aloginauth'])->group(function () {
473 Route::any('/saveTask', [Aside\AutoPull\AutoPullController::class, 'saveTask'])->name('admin.auto_pull_saveTask'); 473 Route::any('/saveTask', [Aside\AutoPull\AutoPullController::class, 'saveTask'])->name('admin.auto_pull_saveTask');
474 Route::any('/taskMap', [Aside\AutoPull\AutoPullController::class, 'taskMap'])->name('admin.auto_pull_taskMap'); 474 Route::any('/taskMap', [Aside\AutoPull\AutoPullController::class, 'taskMap'])->name('admin.auto_pull_taskMap');
475 }); 475 });
  476 + /**
  477 + * 打包静态页面模块
  478 + */
  479 + Route::prefix('pack_dir')->group(function () {
  480 + Route::any('/', [Aside\PackDir\PackDirController::class, 'getTaskLists'])->name('admin.pack_dir_getTaskLists');
  481 + Route::any('/saveTask', [Aside\PackDir\PackDirController::class, 'saveTask'])->name('admin.pack_dir_saveTask');
  482 + });
476 }); 483 });
477 484
478 //无需登录验证的路由组 485 //无需登录验证的路由组