作者 赵彬吉
@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 2
3 namespace App\Console\Commands\Domain; 3 namespace App\Console\Commands\Domain;
4 4
  5 +use App\Models\Geo\GeoCount;
5 use App\Models\Project\DeployBuild; 6 use App\Models\Project\DeployBuild;
6 use App\Models\Project\DeployOptimize; 7 use App\Models\Project\DeployOptimize;
7 use App\Models\Project\Project; 8 use App\Models\Project\Project;
@@ -58,41 +59,31 @@ class RemainDay extends Command @@ -58,41 +59,31 @@ class RemainDay extends Command
58 */ 59 */
59 protected $description = '网站服务剩余时长'; 60 protected $description = '网站服务剩余时长';
60 61
61 - /**  
62 - * Create a new command instance.  
63 - *  
64 - * @return void  
65 - */  
66 - public function __construct()  
67 - {  
68 - $this->project = new Project();  
69 - $this->deployBuild = new DeployBuild();  
70 - parent::__construct();  
71 - }  
72 62
73 /** 63 /**
74 * @return bool 64 * @return bool
75 */ 65 */
76 public function handle() 66 public function handle()
77 { 67 {
78 - $this->saveRemainDay(); 68 + $this->_action();
79 return true; 69 return true;
80 } 70 }
81 71
82 -  
83 -  
84 /** 72 /**
85 - * @remark :普通项目剩余服务时常  
86 - * @name :saveRemainDay 73 + * @remark :计算剩余服务时常
  74 + * @name :_action
87 * @author :lyh 75 * @author :lyh
88 * @method :post 76 * @method :post
89 - * @time :2025/4/2 10:48 77 + * @time :2025/11/4 10:59
90 */ 78 */
91 - public function saveRemainDay(){  
92 - $list = $this->project->list(['extend_type'=>Project::TYPE_ZERO,'type'=>['in',[Project::TYPE_TWO,Project::TYPE_THREE,Project::TYPE_FOUR,Project::TYPE_SIX]]],'id',['id','type','level','uptime','remain_day','is_remain_today','pause_days','finish_remain_day','bm_finish_remain_day']); 79 + public function _action(){
  80 + $projectModel = new Project();
  81 + $deployBuildModel = new DeployBuild();
  82 + $list = $projectModel->list(['extend_type'=>Project::TYPE_ZERO,'type'=>['in',[Project::TYPE_TWO,Project::TYPE_THREE,Project::TYPE_FOUR,Project::TYPE_SIX]]],'id',['id','type','level','uptime','remain_day','version','is_remain_today','pause_days','finish_remain_day','bm_finish_remain_day','geo_qualify_num']);
93 foreach ($list as $item){ 83 foreach ($list as $item){
  84 + $deploy_build = $deployBuildModel->read(['project_id'=>$item['id']],['service_duration','seo_service_duration','plan','seo_plan']);
94 echo 'start->项目id:' . $item['id'] . '执行时间:'. date('Y-m-d H:i:s') . PHP_EOL; 85 echo 'start->项目id:' . $item['id'] . '执行时间:'. date('Y-m-d H:i:s') . PHP_EOL;
95 - $deploy_build = $this->deployBuild->read(['project_id'=>$item['id']],['service_duration','seo_service_duration','plan','seo_plan']); 86 + //todo::暂停的项目停止计时
96 if(in_array($item['id'],$this->ceaseProjectId)){//暂停的项目 87 if(in_array($item['id'],$this->ceaseProjectId)){//暂停的项目
97 if(($item['type'] == Project::TYPE_TWO) && ($item['is_remain_today'] == 1)){ 88 if(($item['type'] == Project::TYPE_TWO) && ($item['is_remain_today'] == 1)){
98 $pause_days = $item['pause_days'] + 1; 89 $pause_days = $item['pause_days'] + 1;
@@ -111,15 +102,14 @@ class RemainDay extends Command @@ -111,15 +102,14 @@ class RemainDay extends Command
111 //白帽版本单独计算 102 //白帽版本单独计算
112 $this->seoRemainDay($deploy_build,$item); 103 $this->seoRemainDay($deploy_build,$item);
113 //默认版本统计 104 //默认版本统计
114 - if($deploy_build['service_duration'] == 0){  
115 - continue;  
116 - }  
117 $this->remainDay($item,$deploy_build); 105 $this->remainDay($item,$deploy_build);
118 echo 'end->项目id:' . $item['id'] . '执行时间:'. date('Y-m-d H:i:s') . PHP_EOL; 106 echo 'end->项目id:' . $item['id'] . '执行时间:'. date('Y-m-d H:i:s') . PHP_EOL;
119 } 107 }
120 return true; 108 return true;
121 } 109 }
122 110
  111 +
  112 +
123 /** 113 /**
124 * @remark :白帽版本单独计算 114 * @remark :白帽版本单独计算
125 * @name :seoRemainDay 115 * @name :seoRemainDay
@@ -140,13 +130,7 @@ class RemainDay extends Command @@ -140,13 +130,7 @@ class RemainDay extends Command
140 $compliance_day = floor($diff / (60 * 60 * 24)); 130 $compliance_day = floor($diff / (60 * 60 * 24));
141 $seo_remain_day = $deploy_build['seo_service_duration'] - $compliance_day; 131 $seo_remain_day = $deploy_build['seo_service_duration'] - $compliance_day;
142 } 132 }
143 - if($deploy_build['plan'] == 0 && $seo_remain_day < 0 && $deploy_build['seo_service_duration'] != 0){//只有白帽版本的项目且剩余服务时常为0,放入未续费中  
144 -// $this->project->edit(['seo_remain_day'=>$seo_remain_day,'finish_remain_day'=>$compliance_day ?? 0,'extend_type'=>Project::TYPE_FIVE],['id'=>$item['id']]);  
145 - $this->project->edit(['seo_remain_day'=>$seo_remain_day,'bm_finish_remain_day'=>$compliance_day ?? 0],['id'=>$item['id']]);  
146 - }else{  
147 - //同时包括白帽版本+默认版本的项目  
148 - $this->project->edit(['seo_remain_day'=>$seo_remain_day,'bm_finish_remain_day'=>$compliance_day ?? 0],['id'=>$item['id']]);  
149 - } 133 + $this->project->edit(['seo_remain_day'=>$seo_remain_day,'bm_finish_remain_day'=>$compliance_day ?? 0],['id'=>$item['id']]);
150 } 134 }
151 } 135 }
152 return true; 136 return true;
@@ -160,6 +144,10 @@ class RemainDay extends Command @@ -160,6 +144,10 @@ class RemainDay extends Command
160 * @time :2025/4/25 14:31 144 * @time :2025/4/25 14:31
161 */ 145 */
162 public function remainDay($item,$deploy_build){ 146 public function remainDay($item,$deploy_build){
  147 + //默认版本统计
  148 + if($deploy_build['service_duration'] == 0){
  149 + return false;
  150 + }
163 //默认版本计算剩余服务时常 151 //默认版本计算剩余服务时常
164 if($item['type'] == Project::TYPE_TWO || $item['type'] == Project::TYPE_FOUR){ 152 if($item['type'] == Project::TYPE_TWO || $item['type'] == Project::TYPE_FOUR){
165 if(in_array($item['id'],$this->projectId)){//已开始优化的时间结算 153 if(in_array($item['id'],$this->projectId)){//已开始优化的时间结算
@@ -173,6 +161,14 @@ class RemainDay extends Command @@ -173,6 +161,14 @@ class RemainDay extends Command
173 $remain_day = $deploy_build['service_duration'] - $compliance_day; 161 $remain_day = $deploy_build['service_duration'] - $compliance_day;
174 }else{ 162 }else{
175 $compliance_day = ($item['finish_remain_day'] ?? 0); 163 $compliance_day = ($item['finish_remain_day'] ?? 0);
  164 + //todo::7.5版本单独计算
  165 + if($item['version'] == 7.5 && $deploy_build['seo_plan'] != 0 && $deploy_build['plan'] != 0){
  166 + $geoCountModel = new GeoCount();
  167 + $is_qualify = $geoCountModel->where('project_id', $item['id'])->orderBy('id', 'desc')->value('is_qualify');
  168 + if($compliance_day > 0 && $is_qualify > 0){
  169 + $compliance_day = 1;
  170 + }
  171 + }
176 $remain_day = $deploy_build['service_duration'] - $compliance_day; 172 $remain_day = $deploy_build['service_duration'] - $compliance_day;
177 } 173 }
178 }else{ 174 }else{
@@ -42,11 +42,14 @@ class GeoWritingsTask extends Command @@ -42,11 +42,14 @@ class GeoWritingsTask extends Command
42 continue; 42 continue;
43 } 43 }
44 echo date("Y-m-d H:i:s").',执行的任务id'.$task_id.PHP_EOL; 44 echo date("Y-m-d H:i:s").',执行的任务id'.$task_id.PHP_EOL;
45 - $info = $geoWritingsTaskModel->read(['id'=>$task_id]); 45 + $info = $geoWritingsTaskModel->read(['id'=>$task_id,'status'=>1]);
46 if($info === false){ 46 if($info === false){
47 - echo date("Y-m-d H:i:s").',任务id数据不存在:'.$task_id.PHP_EOL; 47 + echo date("Y-m-d H:i:s").',任务id数据不存在/或已被执行:'.$task_id.PHP_EOL;
48 continue; 48 continue;
49 } 49 }
  50 + //修改状态为生成中
  51 + $geoWritingsModel = new GeoWritings();
  52 + $geoWritingsModel->edit(['status'=>$geoWritingsModel::STATUS_AI_RUNNING],['id'=>$info['writings_id']]);
50 //生成引言 53 //生成引言
51 $aiCommand1 = "请根据这个文章标题:{$info['title']},并同时参考公司的介绍’{$info['description']}‘以及公司参与的事件内容’{$info['event_content']}‘,给我写一个英文Press Release前言内容,前言内容请参考并引用{$info['keyword']}行业的一些专业数据报告,只需要1个段落,大约150-200字,请一定要出现这个关键词“{$info['prefix']}{$info['keyword']}{$info['suffix']}”,所有内容一定要用英文, 只需要回复我引言内容,不需要别的内容(比如序号、你的提示、寒暄、解释、注释之类的)"; 54 $aiCommand1 = "请根据这个文章标题:{$info['title']},并同时参考公司的介绍’{$info['description']}‘以及公司参与的事件内容’{$info['event_content']}‘,给我写一个英文Press Release前言内容,前言内容请参考并引用{$info['keyword']}行业的一些专业数据报告,只需要1个段落,大约150-200字,请一定要出现这个关键词“{$info['prefix']}{$info['keyword']}{$info['suffix']}”,所有内容一定要用英文, 只需要回复我引言内容,不需要别的内容(比如序号、你的提示、寒暄、解释、注释之类的)";
52 $gptHelper = new Gpt(); 55 $gptHelper = new Gpt();
@@ -57,21 +60,17 @@ class GeoWritingsTask extends Command @@ -57,21 +60,17 @@ class GeoWritingsTask extends Command
57 $images = explode(',',$info['img']); 60 $images = explode(',',$info['img']);
58 //组装一条数据 61 //组装一条数据
59 try { 62 try {
60 - $geoWritingsModel = new GeoWritings();  
61 $saveData = [ 63 $saveData = [
62 - 'project_id'=>$info['project_id'],  
63 - 'type'=>$geoWritingsModel::TYPE_AI_CREATE,  
64 'title'=>$info['title'], 64 'title'=>$info['title'],
65 'content'=>$introduction.($images[0] ?? '').PHP_EOL.$main.($images[1] ?? ''), 65 'content'=>$introduction.($images[0] ?? '').PHP_EOL.$main.($images[1] ?? ''),
66 'content_length'=>strlen($introduction.PHP_EOL.$main), 66 'content_length'=>strlen($introduction.PHP_EOL.$main),
67 - 'uniqid'=>md5(uniqid().$task_id.$info['project_id']), 67 + 'status'=>$geoWritingsModel::STATUS_INIT
68 ]; 68 ];
69 - $id = $geoWritingsModel->addReturnId($saveData); 69 + $geoWritingsModel->edit($saveData,['id'=>$info['writings_id']]);
70 $data = [ 70 $data = [
71 'introduction'=>$introduction, 71 'introduction'=>$introduction,
72 'main'=>$main, 72 'main'=>$main,
73 'status'=>2, 73 'status'=>2,
74 - 'writings_id'=>$id,  
75 ]; 74 ];
76 $geoWritingsTaskModel->edit($data,['id'=>$task_id]); 75 $geoWritingsTaskModel->edit($data,['id'=>$task_id]);
77 }catch (\Exception $e){ 76 }catch (\Exception $e){
@@ -88,20 +87,34 @@ class GeoWritingsTask extends Command @@ -88,20 +87,34 @@ class GeoWritingsTask extends Command
88 * @method :post 87 * @method :post
89 * @time :2025/10/27 14:22 88 * @time :2025/10/27 14:22
90 */ 89 */
91 - public function getTaskId(){ 90 + public function getTaskId()
  91 + {
92 $task_id = Redis::rpop('geo_writings_task'); 92 $task_id = Redis::rpop('geo_writings_task');
93 - $geoWritingsTaskModel = new GeoWritingsTaskModel(); 93 + // 如果队列空了,尝试补充
94 if (empty($task_id)) { 94 if (empty($task_id)) {
95 - $ids = $geoWritingsTaskModel->formatQuery(['status'=>0])->limit(100)->pluck('id');  
96 - if(!empty($ids)){  
97 - foreach ($ids as $id) {  
98 - Redis::lpush('geo_writings_task', $id); 95 + $lock_key = 'geo_writings_task_lock';
  96 + $lock_ttl = 10; // 锁过期时间10秒,防止死锁
  97 + $lock = Redis::set($lock_key, 1, 'EX', $lock_ttl, 'NX');
  98 + if ($lock) {
  99 + try {
  100 + $geoWritingsTaskModel = new GeoWritingsTaskModel();
  101 + $ids = $geoWritingsTaskModel->formatQuery(['status' => 0])->limit(100)->pluck('id');
  102 + if (!$ids->isEmpty()) {
  103 + // 标记这批任务为“生成中”
  104 + $geoWritingsTaskModel->edit(['status' => 1], ['id' => ['in', $ids]]);
  105 + foreach ($ids as $id) {
  106 + Redis::lpush('geo_writings_task', $id);
  107 + }
  108 + }
  109 + } finally {
  110 + // 释放锁
  111 + Redis::del($lock_key);
99 } 112 }
  113 + // 再次从队列中取任务
100 $task_id = Redis::rpop('geo_writings_task'); 114 $task_id = Redis::rpop('geo_writings_task');
101 } 115 }
102 - }else{  
103 - $geoWritingsTaskModel->edit(['status'=>1],['id'=>$task_id]);  
104 } 116 }
105 return $task_id; 117 return $task_id;
106 } 118 }
  119 +
107 } 120 }
@@ -116,7 +116,7 @@ class SyncProject extends Command @@ -116,7 +116,7 @@ class SyncProject extends Command
116 } 116 }
117 $item->status = NoticeLog::STATUS_SUCCESS; 117 $item->status = NoticeLog::STATUS_SUCCESS;
118 $item->save(); 118 $item->save();
119 - echo 'success:' . $item['id'] . '执行时间:' . date('Y-m-d H:i:s') . PHP_EOL; 119 + echo 'success:' . $item['id'] . '执行时间:'. 'ordet_id:'. $order_id . date('Y-m-d H:i:s') . PHP_EOL;
120 }catch (\Exception $e){ 120 }catch (\Exception $e){
121 echo 'error:' . $item['id'] . $e->getMessage() .' line ' . $e->getLine() . '执行时间:' . PHP_EOL; 121 echo 'error:' . $item['id'] . $e->getMessage() .' line ' . $e->getLine() . '执行时间:' . PHP_EOL;
122 errorLog('项目同步失败', $item, $e); 122 errorLog('项目同步失败', $item, $e);
@@ -38,12 +38,11 @@ class SyncFile extends Command @@ -38,12 +38,11 @@ class SyncFile extends Command
38 }else{ 38 }else{
39 $code = $this->synchronizationFile($v['path']); 39 $code = $this->synchronizationFile($v['path']);
40 } 40 }
41 - echo date('Y-m-d H:i:s') . 'code:'. $code . PHP_EOL;  
42 - if((int)$code == 200){  
43 - echo date('Y-m-d H:i:s') . '编辑的path为:'. $v['path'] .',主键id:'. $v['id'] . PHP_EOL;  
44 - $errorFileModel->edit(['status'=>1],['id'=>$v['id']]);  
45 - }  
46 - 41 +// echo date('Y-m-d H:i:s') . 'code:'. $code . PHP_EOL;
  42 +// if((int)$code == 200){
  43 +// echo date('Y-m-d H:i:s') . '编辑的path为:'. $v['path'] .',主键id:'. $v['id'] . PHP_EOL;
  44 +// $errorFileModel->edit(['status'=>1],['id'=>$v['id']]);
  45 +// }
47 } 46 }
48 echo date('Y-m-d H:i:s') . '编辑的end为:' . PHP_EOL; 47 echo date('Y-m-d H:i:s') . '编辑的end为:' . PHP_EOL;
49 return true; 48 return true;
@@ -60,7 +59,7 @@ class SyncFile extends Command @@ -60,7 +59,7 @@ class SyncFile extends Command
60 //同步到大文件 59 //同步到大文件
61 $file_path = config('filesystems.disks.cos')['cdn1'].$path_name; 60 $file_path = config('filesystems.disks.cos')['cdn1'].$path_name;
62 $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME); 61 $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME);
63 - $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$directoryPath.'" https://v6-file.globalso.com/upload.php'; 62 + $cmd = 'curl -k -F "file_path='.$path_name.'" -F "save_path=/www/wwwroot/cos'.$path_name.'" https://v6-file.globalso.com/upload.php';
64 return shell_exec($cmd); 63 return shell_exec($cmd);
65 } 64 }
66 65
@@ -69,7 +68,7 @@ class SyncFile extends Command @@ -69,7 +68,7 @@ class SyncFile extends Command
69 //同步到大文件 68 //同步到大文件
70 $file_path = config('filesystems.disks.s3')['cdn'].$path_name; 69 $file_path = config('filesystems.disks.s3')['cdn'].$path_name;
71 $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME); 70 $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME);
72 - $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$directoryPath.'" https://v6-file.globalso.com/upload.php'; 71 + $cmd = 'curl -k -F "file_path='.$path_name.'" -F "save_path=/www/wwwroot/cos'.$path_name.'" https://v6-file.globalso.com/upload.php';
73 return shell_exec($cmd); 72 return shell_exec($cmd);
74 } 73 }
75 } 74 }
@@ -40,9 +40,9 @@ class SyncProjectFile extends Command @@ -40,9 +40,9 @@ class SyncProjectFile extends Command
40 }else{ 40 }else{
41 $code = $this->synchronizationFile($v['path']); 41 $code = $this->synchronizationFile($v['path']);
42 } 42 }
43 - if((int)$code == 200){ 43 +// if((int)$code == 200){
44 echo date('Y-m-d H:i:s') . '编辑的path为:'. $v['path'] .',主键id:'. $v['id'] . PHP_EOL; 44 echo date('Y-m-d H:i:s') . '编辑的path为:'. $v['path'] .',主键id:'. $v['id'] . PHP_EOL;
45 - } 45 +// }
46 } 46 }
47 echo date('Y-m-d H:i:s') . '编辑的end为:' . PHP_EOL; 47 echo date('Y-m-d H:i:s') . '编辑的end为:' . PHP_EOL;
48 return true; 48 return true;
@@ -59,7 +59,7 @@ class SyncProjectFile extends Command @@ -59,7 +59,7 @@ class SyncProjectFile extends Command
59 //同步到大文件 59 //同步到大文件
60 $file_path = config('filesystems.disks.cos')['cdn1'].$path_name; 60 $file_path = config('filesystems.disks.cos')['cdn1'].$path_name;
61 $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME); 61 $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME);
62 - $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$directoryPath.'" https://v6-file.globalso.com/upload.php'; 62 + $cmd = 'curl -k -F "file_path='.$path_name.'" -F "save_path=/www/wwwroot/cos'.$path_name.'" https://v6-file.globalso.com/upload.php';
63 return shell_exec($cmd); 63 return shell_exec($cmd);
64 } 64 }
65 65
@@ -68,7 +68,7 @@ class SyncProjectFile extends Command @@ -68,7 +68,7 @@ class SyncProjectFile extends Command
68 //同步到大文件 68 //同步到大文件
69 $file_path = config('filesystems.disks.s3')['cdn'].$path_name; 69 $file_path = config('filesystems.disks.s3')['cdn'].$path_name;
70 $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME); 70 $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME);
71 - $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$directoryPath.'" https://v6-file.globalso.com/upload.php'; 71 + $cmd = 'curl -k -F "file_path='.$path_name.'" -F "save_path=/www/wwwroot/cos'.$path_name.'" https://v6-file.globalso.com/upload.php';
72 return shell_exec($cmd); 72 return shell_exec($cmd);
73 } 73 }
74 } 74 }
@@ -33,18 +33,13 @@ class SyncTimeFiles extends Command @@ -33,18 +33,13 @@ class SyncTimeFiles extends Command
33 { 33 {
34 // $fileModel = new File(); 34 // $fileModel = new File();
35 $imagesModel = new Image(); 35 $imagesModel = new Image();
36 - $start = '2025-08-28 00:00:00';  
37 - $end = '2025-08-29 23:59:59';  
38 - $lists = $imagesModel->list(['created_at'=>['between',[$start,$end]]]); 36 + $start = '2025-10-13 17:20:00';
  37 + $end = '2025-10-31 23:59:59';
  38 + $lists = $imagesModel->list(['created_at'=>['between',[$start,$end]]],'id',['path'],'asc');
39 foreach ($lists as $v){ 39 foreach ($lists as $v){
40 $path = $v['path']; 40 $path = $v['path'];
41 echo date('Y-m-d H:i:s') . ' | 图片链接:' . $path . PHP_EOL; 41 echo date('Y-m-d H:i:s') . ' | 图片链接:' . $path . PHP_EOL;
42 $code = $this->synchronizationFile($path); 42 $code = $this->synchronizationFile($path);
43 - if(200 != (int)$code){  
44 - echo date('Y-m-d H:i:s') . ' | 错误状态:' . $code . PHP_EOL;  
45 - $errorFileModel = new ErrorFile();  
46 - $errorFileModel->add(['path'=>$this->param['path'].'/'.$this->param['name']]);  
47 - }  
48 echo date('Y-m-d H:i:s') . ' | ok:' . $code . PHP_EOL; 43 echo date('Y-m-d H:i:s') . ' | ok:' . $code . PHP_EOL;
49 } 44 }
50 return true; 45 return true;
@@ -52,9 +47,7 @@ class SyncTimeFiles extends Command @@ -52,9 +47,7 @@ class SyncTimeFiles extends Command
52 47
53 public function synchronizationFile($path_name){ 48 public function synchronizationFile($path_name){
54 //同步到大文件 49 //同步到大文件
55 - $file_path = config('filesystems.disks.cos')['cdn1'].$path_name;  
56 - $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME);  
57 - $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$directoryPath.'" https://v6-file.globalso.com/upload.php'; 50 + $cmd = 'curl -k -F "file_path='.$path_name.'" -F "save_path=/www/wwwroot/cos'.$path_name.'" https://v6-file.globalso.com/upload.php';
58 return shell_exec($cmd); 51 return shell_exec($cmd);
59 } 52 }
60 53
@@ -52,11 +52,6 @@ class SyncTimeMinuteFile extends Command @@ -52,11 +52,6 @@ class SyncTimeMinuteFile extends Command
52 // continue; 52 // continue;
53 // } 53 // }
54 $code = $this->synchronizationFile($path); 54 $code = $this->synchronizationFile($path);
55 - if(200 != (int)$code){  
56 - echo date('Y-m-d H:i:s') . ' | 错误状态:' . $code . PHP_EOL;  
57 - $errorFileModel = new ErrorFile();  
58 - $errorFileModel->add(['path'=>$this->param['path'].'/'.$this->param['name']]);  
59 - }  
60 echo date('Y-m-d H:i:s') . ' | ok:' . $code . PHP_EOL; 55 echo date('Y-m-d H:i:s') . ' | ok:' . $code . PHP_EOL;
61 } 56 }
62 return true; 57 return true;
@@ -66,7 +61,7 @@ class SyncTimeMinuteFile extends Command @@ -66,7 +61,7 @@ class SyncTimeMinuteFile extends Command
66 //同步到大文件 61 //同步到大文件
67 $file_path = config('filesystems.disks.cos')['cdn1'].$path_name; 62 $file_path = config('filesystems.disks.cos')['cdn1'].$path_name;
68 $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME); 63 $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME);
69 - $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$directoryPath.'" https://v6-file.globalso.com/upload.php'; 64 + $cmd = 'curl -k -F "file_path='.$path_name.'" -F "save_path=/www/wwwroot/cos'.$path_name.'" https://v6-file.globalso.com/upload.php';
70 return shell_exec($cmd); 65 return shell_exec($cmd);
71 } 66 }
72 67
@@ -32,11 +32,6 @@ class SyncVideo extends Command @@ -32,11 +32,6 @@ class SyncVideo extends Command
32 $path = $this->argument('path'); 32 $path = $this->argument('path');
33 $code = $this->synchronizationFile($path); 33 $code = $this->synchronizationFile($path);
34 echo date('Y-m-d H:i:s') . ' | ' . $code . PHP_EOL; 34 echo date('Y-m-d H:i:s') . ' | ' . $code . PHP_EOL;
35 - if(200 != (int)$code){  
36 - echo date('Y-m-d H:i:s') . ' | ' . $code . PHP_EOL;  
37 - $errorFileModel = new ErrorFile();  
38 - $errorFileModel->add(['path'=>$this->param['path'].'/'.$this->param['name']]);  
39 - }  
40 return true; 35 return true;
41 } 36 }
42 37
@@ -44,7 +39,7 @@ class SyncVideo extends Command @@ -44,7 +39,7 @@ class SyncVideo extends Command
44 //同步到大文件 39 //同步到大文件
45 $file_path = config('filesystems.disks.cos')['cdn1'].$path_name; 40 $file_path = config('filesystems.disks.cos')['cdn1'].$path_name;
46 $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME); 41 $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME);
47 - $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$directoryPath.'" https://v6-file.globalso.com/upload.php'; 42 + $cmd = 'curl -k -F "file_path='.$path_name.'" -F "save_path=/www/wwwroot/cos'.$path_name.'" https://v6-file.globalso.com/upload.php';
48 return shell_exec($cmd); 43 return shell_exec($cmd);
49 } 44 }
50 45
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :ManageEntryPositionController.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/11/3 17:13
  8 + */
  9 +
  10 +namespace App\Http\Controllers\Aside\Manage;
  11 +
  12 +use App\Enums\Common\Code;
  13 +use App\Http\Controllers\Aside\BaseController;
  14 +use App\Http\Logic\Aside\Manage\ManageEntryPositionLogic;
  15 +use Illuminate\Http\Request;
  16 +
  17 +/**
  18 + * @remark :岗位管理
  19 + * @name :ManageEntryPositionController
  20 + * @author :lyh
  21 + * @method :post
  22 + * @time :2025/11/3 17:13
  23 + */
  24 +class ManageEntryPositionController extends BaseController
  25 +{
  26 + /**
  27 + * @param Request $request
  28 + */
  29 + public function __construct(Request $request)
  30 + {
  31 + parent::__construct($request);
  32 + $this->logic = new ManageEntryPositionLogic();
  33 + }
  34 +
  35 + /**
  36 + * @remark :列表数据
  37 + * @name :lists
  38 + * @author :lyh
  39 + * @method :post
  40 + * @time :2025/11/3 17:20
  41 + */
  42 + public function lists()
  43 + {
  44 + $data = $this->logic->listEntryPosition();
  45 + $this->response('success',Code::SUCCESS,$data);
  46 + }
  47 +
  48 + /**
  49 + * @remark :保存数据
  50 + * @name :save
  51 + * @author :lyh
  52 + * @method :post
  53 + * @time :2025/11/3 17:20
  54 + */
  55 + public function save()
  56 + {
  57 + $this->request->validate([
  58 + 'name'=>'required'
  59 + ],[
  60 + 'name.required' => 'name不能为空'
  61 + ]);
  62 + $data = $this->logic->saveEntryPosition();
  63 + $this->response('success',Code::SUCCESS,$data);
  64 + }
  65 +
  66 + /**
  67 + * @remark :删除数据
  68 + * @name :del
  69 + * @author :lyh
  70 + * @method :post
  71 + * @time :2025/11/3 17:20
  72 + */
  73 + public function del()
  74 + {
  75 + $this->request->validate([
  76 + 'id'=>'required|array'
  77 + ],[
  78 + 'id.required' => 'ID不能为空'
  79 + ]);
  80 + $data = $this->logic->delEntryPosition();
  81 + $this->response('success',Code::SUCCESS,$data);
  82 + }
  83 +}
@@ -16,6 +16,7 @@ use App\Models\Geo\GeoLink; @@ -16,6 +16,7 @@ use App\Models\Geo\GeoLink;
16 use App\Models\Geo\GeoQuestion; 16 use App\Models\Geo\GeoQuestion;
17 use App\Models\Geo\GeoWritings; 17 use App\Models\Geo\GeoWritings;
18 use App\Models\Manage\ManageHr; 18 use App\Models\Manage\ManageHr;
  19 +use App\Models\Project\DeployBuild;
19 use App\Models\Project\KeywordPrefix; 20 use App\Models\Project\KeywordPrefix;
20 use App\Models\Project\Project; 21 use App\Models\Project\Project;
21 22
@@ -48,15 +49,19 @@ class GeoLogic extends BaseLogic @@ -48,15 +49,19 @@ class GeoLogic extends BaseLogic
48 $project_geo_conf = $projectModel->read(['id' => $project_id],['title', 'version', 'geo_status', 'geo_qualify_num']); 49 $project_geo_conf = $projectModel->read(['id' => $project_id],['title', 'version', 'geo_status', 'geo_qualify_num']);
49 $geoConfModel = new GeoConf(); 50 $geoConfModel = new GeoConf();
50 $geo_conf = $geoConfModel->read(['project_id' => $project_id]); 51 $geo_conf = $geoConfModel->read(['project_id' => $project_id]);
  52 + $deployModel = new DeployBuild();
  53 + $seo_plan = $deployModel->getValue(['project_id'=>$project_id],'seo_plan');
  54 + $seo_plan_name = ($projectModel::seoMap()[$seo_plan]) ?? '无选择';
  55 + $geo_conf['seo_plan_name'] = $seo_plan_name;
51 if($geo_conf === false){//数据未初始化 56 if($geo_conf === false){//数据未初始化
52 $geo_conf = [ 57 $geo_conf = [
53 - 'project_id' => $project_id, 'manager_id'=>0, 'company'=>$project_geo_conf['title'], 'brand'=>'', 'description'=>'' 58 + 'project_id' => $project_id, 'manager_id'=>0, 'company'=>$project_geo_conf['title'], 'brand'=>'', 'description'=>'','seo_plan_name'=>$seo_plan_name
54 ]; 59 ];
55 } 60 }
56 //负责人集合 61 //负责人集合
57 $geo_manage_list = $geoConfModel->geoManage(); 62 $geo_manage_list = $geoConfModel->geoManage();
58 // geo配置管理员,已经移除管理员列表,补充管理员信息 63 // geo配置管理员,已经移除管理员列表,补充管理员信息
59 - if ($geo_conf && $geo_conf['manager_id'] && empty($geo_manage_list[$geo_conf['manager_id']])) { 64 + if ($geo_conf && isset($geo_conf['manager_id']) && empty($geo_manage_list[$geo_conf['manager_id']])) {
60 $manage = ManageHr::where(['id' => $geo_conf['manager_id']])->pluck('name', 'id')->toArray(); 65 $manage = ManageHr::where(['id' => $geo_conf['manager_id']])->pluck('name', 'id')->toArray();
61 $geo_manage_list = array_merge($geo_manage_list, $manage); 66 $geo_manage_list = array_merge($geo_manage_list, $manage);
62 } 67 }
@@ -49,6 +49,11 @@ class GeoWritingsTaskLogic extends BaseLogic @@ -49,6 +49,11 @@ class GeoWritingsTaskLogic extends BaseLogic
49 $id = $this->param['id']; 49 $id = $this->param['id'];
50 $this->model->edit($this->param,['id'=>$id]); 50 $this->model->edit($this->param,['id'=>$id]);
51 }else{ 51 }else{
  52 + //自动保存一条数据
  53 + $writingModel = new GeoWritings();
  54 + $this->param['writings_id'] = $writingModel->addReturnId(['project_id'=>$this->param['project_id'],
  55 + 'type'=>$writingModel::TYPE_AI_CREATE,'status'=>$writingModel::STATUS_AI_WAIT,
  56 + 'uniqid'=>md5(uniqid().rand(1, 99999).$this->param['project_id'])]);
52 $id = $this->model->addReturnId($this->param); 57 $id = $this->model->addReturnId($this->param);
53 } 58 }
54 }catch (\Exception $e){ 59 }catch (\Exception $e){
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :ManageEntryPositionLogic.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/11/3 17:14
  8 + */
  9 +
  10 +namespace App\Http\Logic\Aside\Manage;
  11 +
  12 +use App\Http\Logic\Aside\BaseLogic;
  13 +use App\Models\Manage\EntryPosition;
  14 +
  15 +class ManageEntryPositionLogic extends BaseLogic
  16 +{
  17 + public function __construct()
  18 + {
  19 + parent::__construct();
  20 + $this->param = $this->requestAll;
  21 + $this->model = new EntryPosition();
  22 + }
  23 +
  24 + /**
  25 + * @remark :列表数据
  26 + * @name :listEntryPosition
  27 + * @author :lyh
  28 + * @method :post
  29 + * @time :2025/11/3 17:27
  30 + */
  31 + public function listEntryPosition($map = [],$page = 1, $row = 10,$order = 'id')
  32 + {
  33 + $data = $this->model->lists($map,$page,$row,$order);
  34 + return $this->success($data);
  35 + }
  36 +
  37 + /**
  38 + * @remark :保存数据
  39 + * @name :saveEntryPosition
  40 + * @author :lyh
  41 + * @method :post
  42 + * @time :2025/11/3 17:28
  43 + */
  44 + public function saveEntryPosition()
  45 + {
  46 + try {
  47 + if(isset($this->param['id']) && !empty($this->param['id'])){
  48 + $id = $this->param['id'];
  49 + $this->model->edit($this->param,['id'=>$id]);
  50 + }else{
  51 + $id = $this->model->addReturnId($this->param);
  52 + }
  53 + }catch (\Exception $e){
  54 + $this->fail('保存失败,请联系管理员'.$e->getMessage());
  55 + }
  56 + return $this->success(['id'=>$id]);
  57 + }
  58 +
  59 + /**
  60 + * @remark :删除数据
  61 + * @name :delEntryPosition
  62 + * @author :lyh
  63 + * @method :post
  64 + * @time :2025/11/3 17:28
  65 + */
  66 + public function delEntryPosition()
  67 + {
  68 + $this->model->del(['id'=>['in',$this->param['id']]]);
  69 + return $this->success();
  70 + }
  71 +}
@@ -528,22 +528,23 @@ class InquiryForwardLogic extends BaseLogic @@ -528,22 +528,23 @@ class InquiryForwardLogic extends BaseLogic
528 { 528 {
529 $data = Cache::get('inquiry_manage_count'); 529 $data = Cache::get('inquiry_manage_count');
530 if (!$data) { 530 if (!$data) {
531 - $manage_ids = ForwardCount::select('manage_id')->orderBy('manage_id', 'asc')->distinct()->pluck('manage_id')->toArray();  
532 $manageModel = new Manage(); 531 $manageModel = new Manage();
533 532
534 //月统计 533 //月统计
  534 + $last_year_month = date('Y-m', strtotime('-11 months'));
  535 + $month_manage_ids = ForwardCount::select('manage_id')->where('created_at', '>', $last_year_month . '-02')->where('count', '>', 0)->orderBy('manage_id', 'asc')->distinct()->pluck('manage_id')->toArray();
  536 +
535 $data_month = []; 537 $data_month = [];
536 $data_month_total = []; 538 $data_month_total = [];
537 $now_month = date('Y-m'); 539 $now_month = date('Y-m');
538 - $last_year_month = date('Y-m', strtotime('-11 months'));  
539 while ($last_year_month <= $now_month) { 540 while ($last_year_month <= $now_month) {
540 $month_arr = explode('-', $last_year_month); 541 $month_arr = explode('-', $last_year_month);
541 $year = $month_arr[0]; 542 $year = $month_arr[0];
542 $month = $month_arr[1]; 543 $month = $month_arr[1];
543 544
544 - foreach ($manage_ids as $mid) {  
545 - $name = $manageModel->getName($mid);  
546 - $month_count = intval(ForwardCount::where('manage_id', $mid)->where('year', $year)->where('month', $month)->sum('count') ?? 0); 545 + foreach ($month_manage_ids as $month_mid) {
  546 + $name = $manageModel->getName($month_mid);
  547 + $month_count = intval(ForwardCount::where('manage_id', $month_mid)->where('year', $year)->where('month', $month)->sum('count') ?? 0);
547 $data_month_total[$name] = ($data_month_total[$name] ?? 0) + $month_count; 548 $data_month_total[$name] = ($data_month_total[$name] ?? 0) + $month_count;
548 $data_month[$last_year_month][$name] = $month_count; 549 $data_month[$last_year_month][$name] = $month_count;
549 } 550 }
@@ -554,19 +555,21 @@ class InquiryForwardLogic extends BaseLogic @@ -554,19 +555,21 @@ class InquiryForwardLogic extends BaseLogic
554 555
555 556
556 //周统计 557 //周统计
  558 + $last_week_day = date('Y-m-d', strtotime('-1 week'));
  559 + $week_manage_ids = ForwardCount::select('manage_id')->where('created_at', '>', $last_week_day . ' +1 day')->where('count', '>', 0)->orderBy('manage_id', 'asc')->distinct()->pluck('manage_id')->toArray();
  560 +
557 $data_week = []; 561 $data_week = [];
558 $data_week_total = []; 562 $data_week_total = [];
559 $now_day = date('Y-m-d'); 563 $now_day = date('Y-m-d');
560 - $last_week_day = date('Y-m-d', strtotime('-1 week'));  
561 while ($last_week_day < $now_day) { 564 while ($last_week_day < $now_day) {
562 $day_arr = explode('-', $last_week_day); 565 $day_arr = explode('-', $last_week_day);
563 $year = $day_arr[0]; 566 $year = $day_arr[0];
564 $month = $day_arr[1]; 567 $month = $day_arr[1];
565 $day = $day_arr[2]; 568 $day = $day_arr[2];
566 569
567 - foreach ($manage_ids as $mid) {  
568 - $name = $manageModel->getName($mid);  
569 - $day_count = ForwardCount::where('manage_id', $mid)->where('year', $year)->where('month', $month)->where('day', $day)->value('count') ?? 0; 570 + foreach ($week_manage_ids as $week_mid) {
  571 + $name = $manageModel->getName($week_mid);
  572 + $day_count = ForwardCount::where('manage_id', $week_mid)->where('year', $year)->where('month', $month)->where('day', $day)->value('count') ?? 0;
570 $data_week_total[$name] = ($data_week_total[$name] ?? 0) + $day_count; 573 $data_week_total[$name] = ($data_week_total[$name] ?? 0) + $day_count;
571 $data_week[substr($last_week_day, 5)][$name] = $day_count; 574 $data_week[substr($last_week_day, 5)][$name] = $day_count;
572 } 575 }
@@ -170,6 +170,15 @@ class TicketUploadDataLogic extends BaseLogic @@ -170,6 +170,15 @@ class TicketUploadDataLogic extends BaseLogic
170 return $this->success($data); 170 return $this->success($data);
171 } 171 }
172 172
  173 + public function setProductSort($mdoel){
  174 + $info = $mdoel->orderBy('sort','desc')->first();
  175 + if(empty($info)){
  176 + return 1;
  177 + }
  178 + $sort = $info['sort']+1;
  179 + return $sort;
  180 + }
  181 +
173 /** 182 /**
174 * @remark :保存数据详情 183 * @remark :保存数据详情
175 * @name :saveData 184 * @name :saveData
@@ -196,6 +205,7 @@ class TicketUploadDataLogic extends BaseLogic @@ -196,6 +205,7 @@ class TicketUploadDataLogic extends BaseLogic
196 } 205 }
197 try { 206 try {
198 $productModel = new Product(); 207 $productModel = new Product();
  208 + $sort = $this->setProductSort($productModel);
199 $data = [ 209 $data = [
200 'project_id' => $info['project_id'], 210 'project_id' => $info['project_id'],
201 'title' => $info['text']['title'], 211 'title' => $info['text']['title'],
@@ -205,6 +215,7 @@ class TicketUploadDataLogic extends BaseLogic @@ -205,6 +215,7 @@ class TicketUploadDataLogic extends BaseLogic
205 'category_id'=>$category_id ?? '', 215 'category_id'=>$category_id ?? '',
206 'keyword_id'=>$keyword_id ?? '', 216 'keyword_id'=>$keyword_id ?? '',
207 'status'=>1, 217 'status'=>1,
  218 + 'sort'=>$sort,
208 ]; 219 ];
209 $id = $productModel->addReturnId($data); 220 $id = $productModel->addReturnId($data);
210 CategoryRelated::saveRelated($id, $info['text']['category_id'] ?? []);//分类关联 221 CategoryRelated::saveRelated($id, $info['text']['category_id'] ?? []);//分类关联
@@ -237,6 +248,8 @@ class TicketUploadDataLogic extends BaseLogic @@ -237,6 +248,8 @@ class TicketUploadDataLogic extends BaseLogic
237 if(isset($info['text']['image'])){ 248 if(isset($info['text']['image'])){
238 $info['text']['image'] = str_replace_url($info['text']['image'] ?? ''); 249 $info['text']['image'] = str_replace_url($info['text']['image'] ?? '');
239 } 250 }
  251 + $blogModel = new Blog();
  252 + $sort = $this->setProductSort($blogModel);
240 $data = [ 253 $data = [
241 'project_id' => $info['project_id'], 254 'project_id' => $info['project_id'],
242 'name' => $info['text']['title'], 255 'name' => $info['text']['title'],
@@ -245,9 +258,10 @@ class TicketUploadDataLogic extends BaseLogic @@ -245,9 +258,10 @@ class TicketUploadDataLogic extends BaseLogic
245 'remark'=>$info['text']['intro'] ?? '', 258 'remark'=>$info['text']['intro'] ?? '',
246 'category_id'=>$category_id ?? '', 259 'category_id'=>$category_id ?? '',
247 'status'=>1, 260 'status'=>1,
  261 + 'sort'=>$sort,
248 ]; 262 ];
249 try { 263 try {
250 - $blogModel = new Blog(); 264 +
251 $id = $blogModel->addReturnId($data); 265 $id = $blogModel->addReturnId($data);
252 $route = RouteMap::setRoute($data['name'],RouteMap::SOURCE_BLOG,$id,$info['project_id']); 266 $route = RouteMap::setRoute($data['name'],RouteMap::SOURCE_BLOG,$id,$info['project_id']);
253 $blogModel->edit(['url'=>$route],['id'=>$id]); 267 $blogModel->edit(['url'=>$route],['id'=>$id]);
@@ -272,6 +286,8 @@ class TicketUploadDataLogic extends BaseLogic @@ -272,6 +286,8 @@ class TicketUploadDataLogic extends BaseLogic
272 if(isset($info['text']['image'])){ 286 if(isset($info['text']['image'])){
273 $info['text']['image'] = str_replace_url($info['text']['image'] ?? ''); 287 $info['text']['image'] = str_replace_url($info['text']['image'] ?? '');
274 } 288 }
  289 + $newsModel = new News();
  290 + $sort = $this->setProductSort($newsModel);
275 $data = [ 291 $data = [
276 'project_id' => $info['project_id'], 292 'project_id' => $info['project_id'],
277 'name' => $info['text']['title'], 293 'name' => $info['text']['title'],
@@ -280,9 +296,10 @@ class TicketUploadDataLogic extends BaseLogic @@ -280,9 +296,10 @@ class TicketUploadDataLogic extends BaseLogic
280 'remark'=>$info['text']['intro'] ?? '', 296 'remark'=>$info['text']['intro'] ?? '',
281 'category_id'=>$category_id ?? '', 297 'category_id'=>$category_id ?? '',
282 'status'=>1, 298 'status'=>1,
  299 + 'sort'=>$sort,
283 ]; 300 ];
284 try { 301 try {
285 - $newsModel = new News(); 302 +
286 $id = $newsModel->addReturnId($data); 303 $id = $newsModel->addReturnId($data);
287 $route = RouteMap::setRoute($data['name'],RouteMap::SOURCE_NEWS,$id,$info['project_id']); 304 $route = RouteMap::setRoute($data['name'],RouteMap::SOURCE_NEWS,$id,$info['project_id']);
288 $newsModel->edit(['url'=>$route],['id'=>$id]); 305 $newsModel->edit(['url'=>$route],['id'=>$id]);
@@ -32,6 +32,9 @@ class SettingFaqLogic extends BaseLogic @@ -32,6 +32,9 @@ class SettingFaqLogic extends BaseLogic
32 public function getRouteList($map = []) 32 public function getRouteList($map = [])
33 { 33 {
34 $routeModel = new RouteMap(); 34 $routeModel = new RouteMap();
  35 + if(!empty($map['route'])){
  36 + $map['route'] = ['like','%'.$map['route'].'%'];
  37 + }
35 $list = $routeModel->list($map,'id',['*'],'desc',20); 38 $list = $routeModel->list($map,'id',['*'],'desc',20);
36 return $this->success($list); 39 return $this->success($list);
37 } 40 }
@@ -5,7 +5,7 @@ namespace App\Models\Manage; @@ -5,7 +5,7 @@ namespace App\Models\Manage;
5 use App\Models\Base; 5 use App\Models\Base;
6 6
7 /** 7 /**
8 - * @remark : 8 + * @remark :岗位管理
9 * @class :EntryPosition.php 9 * @class :EntryPosition.php
10 * @author :lyh 10 * @author :lyh
11 * @time :2023/7/22 18:08 11 * @time :2023/7/22 18:08
@@ -679,7 +679,12 @@ Route::middleware(['aloginauth'])->group(function () { @@ -679,7 +679,12 @@ Route::middleware(['aloginauth'])->group(function () {
679 Route::any('/save', [Aside\Ticket\TicketUploadDataController::class,'save'])->name('ticket_upload_save'); 679 Route::any('/save', [Aside\Ticket\TicketUploadDataController::class,'save'])->name('ticket_upload_save');
680 Route::any('/detail', [Aside\Ticket\TicketUploadDataController::class,'detail'])->name('ticket_upload_detail'); 680 Route::any('/detail', [Aside\Ticket\TicketUploadDataController::class,'detail'])->name('ticket_upload_detail');
681 }); 681 });
682 - 682 + //岗位管理
  683 + Route::prefix('entry_position')->group(function () {
  684 + Route::any('/', [Aside\Manage\ManageEntryPositionController::class,'lists'])->name('entry_position_lists');
  685 + Route::any('/save', [Aside\Manage\ManageEntryPositionController::class,'save'])->name('entry_position_save');
  686 + Route::any('/del', [Aside\Manage\ManageEntryPositionController::class,'del'])->name('entry_position_del');
  687 + });
683 688
684 }); 689 });
685 690