作者 刘锟

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

@@ -100,6 +100,9 @@ class AiBlogAutoPublish extends Command @@ -100,6 +100,9 @@ class AiBlogAutoPublish extends Command
100 //2、未达标的项目,开启AIblog, 并立即推送三篇; 100 //2、未达标的项目,开启AIblog, 并立即推送三篇;
101 //3、其他项目等下下周 1 (2025-03-17)开始推送第一篇, 之后按照正频率发送; 101 //3、其他项目等下下周 1 (2025-03-17)开始推送第一篇, 之后按照正频率发送;
102 if (!$last_task) { 102 if (!$last_task) {
  103 + if(strpos($frequency[0],'/')){
  104 + $frequency = [1,1];//默认每天执行
  105 + }
103 if(!$compliance) { 106 if(!$compliance) {
104 for ($i = 0; $i < 3; $i++) { 107 for ($i = 0; $i < 3; $i++) {
105 $this->createTask($keywords, $project->id, $frequency); 108 $this->createTask($keywords, $project->id, $frequency);
@@ -110,7 +113,18 @@ class AiBlogAutoPublish extends Command @@ -110,7 +113,18 @@ class AiBlogAutoPublish extends Command
110 } 113 }
111 } 114 }
112 } else { 115 } else {
113 - $this->createTask($keywords, $project->id, $frequency); 116 + if($frequency[0] == '1/2'){//一天2篇
  117 + $aiBlogTaskModel = new AiBlogTaskModel();
  118 + $frequency = explode('/', $frequency[0]);
  119 + //查询当前已发布几篇
  120 + $count = $aiBlogTaskModel->counts(['next_auto_date' => date('Y-m-d'),'project_id' => $project->id]);
  121 + while ($count < ($frequency[1] ?? 2)){
  122 + $this->createTask($keywords, $project->id, [$frequency[0],$frequency[0]]);
  123 + $count++;
  124 + }
  125 + }else{
  126 + $this->createTask($keywords, $project->id, $frequency);
  127 + }
114 } 128 }
115 }catch (\Exception $e){ 129 }catch (\Exception $e){
116 (new DingService())->handle([ 130 (new DingService())->handle([
@@ -133,7 +147,7 @@ class AiBlogAutoPublish extends Command @@ -133,7 +147,7 @@ class AiBlogAutoPublish extends Command
133 $result = $aiBlogService->createTask($keyword); 147 $result = $aiBlogService->createTask($keyword);
134 if ($result['status'] == 200) { 148 if ($result['status'] == 200) {
135 $aiBlogTaskModel = new AiBlogTaskModel(); 149 $aiBlogTaskModel = new AiBlogTaskModel();
136 - $next_auto_date = date('Y-m-d', strtotime('+' . mt_rand($frequency[0],$frequency[1]) . 'days')); //每3-6天自动发布 150 + $next_auto_date = date('Y-m-d', strtotime('+' . mt_rand($frequency[0] ?? 3, $frequency[1] ?? 6) . 'days')); //每3-6天自动发布
137 $aiBlogTaskModel->addReturnId(['project_id' => $project_id, 'type' => 2, 'task_id' => $result['data']['task_id'], 'status' => 1, 'next_auto_date' => $next_auto_date]); 151 $aiBlogTaskModel->addReturnId(['project_id' => $project_id, 'type' => 2, 'task_id' => $result['data']['task_id'], 'status' => 1, 'next_auto_date' => $next_auto_date]);
138 ProjectServer::useProject($project_id); 152 ProjectServer::useProject($project_id);
139 $aiBlogModel = new AiBlog(); 153 $aiBlogModel = new AiBlog();
@@ -141,7 +155,6 @@ class AiBlogAutoPublish extends Command @@ -141,7 +155,6 @@ class AiBlogAutoPublish extends Command
141 $end = strtotime('16:00:00'); 155 $end = strtotime('16:00:00');
142 $randomTimestamp = mt_rand($start, $end); 156 $randomTimestamp = mt_rand($start, $end);
143 $created_at = date("Y-m-d H:i:s", $randomTimestamp); 157 $created_at = date("Y-m-d H:i:s", $randomTimestamp);
144 -  
145 $aiBlogModel->addReturnId(['keyword' => $keyword, 'status' => 1, 'task_id' => $result['data']['task_id'], 'project_id' => $project_id, 'created_at' => $created_at]); 158 $aiBlogModel->addReturnId(['keyword' => $keyword, 'status' => 1, 'task_id' => $result['data']['task_id'], 'project_id' => $project_id, 'created_at' => $created_at]);
146 DB::disconnect('custom_mysql'); 159 DB::disconnect('custom_mysql');
147 $this->output("任务创建成功"); 160 $this->output("任务创建成功");
@@ -293,6 +293,9 @@ class AiBlogTask extends Command @@ -293,6 +293,9 @@ class AiBlogTask extends Command
293 $domainModel = new DomainInfo(); 293 $domainModel = new DomainInfo();
294 $project_model = new Project(); 294 $project_model = new Project();
295 foreach ($routes as $project_id => $route){ 295 foreach ($routes as $project_id => $route){
  296 + if($project_id == 4339){
  297 + continue;
  298 + }
296 $route[] = 'top-blog'; 299 $route[] = 'top-blog';
297 $domain = $domainModel->getProjectIdDomain($project_id); 300 $domain = $domainModel->getProjectIdDomain($project_id);
298 if (empty($domain)) { 301 if (empty($domain)) {
@@ -118,7 +118,7 @@ class RemainDay extends Command @@ -118,7 +118,7 @@ class RemainDay extends Command
118 */ 118 */
119 public function seoRemainDay($deploy_build,$item){ 119 public function seoRemainDay($deploy_build,$item){
120 //白帽版本的系统 120 //白帽版本的系统
121 - if($deploy_build['seo_plan'] == 1){ 121 + if($deploy_build['seo_plan'] != 0){
122 if($deploy_build['seo_service_duration'] != 0){ 122 if($deploy_build['seo_service_duration'] != 0){
123 if(in_array($item['id'],$this->bm_projectId) || (in_array( 19,$item['level']))){ 123 if(in_array($item['id'],$this->bm_projectId) || (in_array( 19,$item['level']))){
124 $compliance_day = (int)$item['bm_finish_remain_day']; 124 $compliance_day = (int)$item['bm_finish_remain_day'];
@@ -119,24 +119,23 @@ class GeoQuestionRes extends Command @@ -119,24 +119,23 @@ class GeoQuestionRes extends Command
119 $hit_data = array_merge($url, $title, $hit_data); 119 $hit_data = array_merge($url, $title, $hit_data);
120 } 120 }
121 $hit = 0; 121 $hit = 0;
122 - //todo::与预期结果是否复合  
123 - if(!empty($taskInfo['expect_result'])){  
124 - $str = "客户提出的问题:{$question},客户得到的回复:{$result['text']},客户需要预期:{$taskInfo['expect_result']},请分析得到的回复和预期是否一致,仅回复我是或者否";  
125 - $strResult = $geo_service->getChatResult($str, 'gpt-4o-mini');  
126 - if(isset($strResult['text']) && !empty($strResult['text'])){  
127 - switch ($strResult['text']){  
128 - case '是':  
129 - $is_match = 1;  
130 - $hit++;  
131 - break;  
132 - case '否':  
133 - $is_match = 2;  
134 - break;  
135 - default:  
136 - $is_match = 0;  
137 - break;  
138 - } 122 + $is_match = 0;
  123 + $cosine = 0;
  124 + $similarity = [];
  125 + // TODO 有预期结果,分析答案和预期结果
  126 + if(FALSE == empty($taskInfo['expect_result'])){
  127 + $cosine_result = $geo_service->cosineSimilarity($taskInfo['expect_result'], $result['text']);
  128 + // 语义是否一致
  129 + if (FALSE == empty($cosine_result['judgement'])) {
  130 + $is_match = $cosine_result['judgement'] == '语义相近' ? 1 : 2;
  131 + $hit++;
139 } 132 }
  133 + // 余弦相似度
  134 + if (FALSE == empty($cosine_result['similarity']))
  135 + $cosine = intval($cosine_result['similarity'] * 10000) / 100;
  136 + // 语句拆解结果
  137 + if (FALSE == empty($cosine_result['split_results']))
  138 + $similarity = $cosine_result['split_results'];
140 } 139 }
141 $hit_keyword = $this->getKeywords($taskInfo['keywords'],$hit_data); 140 $hit_keyword = $this->getKeywords($taskInfo['keywords'],$hit_data);
142 if (!empty($hit_keyword['keywords'])) { 141 if (!empty($hit_keyword['keywords'])) {
@@ -165,6 +164,8 @@ class GeoQuestionRes extends Command @@ -165,6 +164,8 @@ class GeoQuestionRes extends Command
165 'url_num'=>$url_num ?? [], 164 'url_num'=>$url_num ?? [],
166 'is_match'=>$is_match ?? 0, 165 'is_match'=>$is_match ?? 0,
167 'label'=>$taskInfo['label'] ?? null, 166 'label'=>$taskInfo['label'] ?? null,
  167 + 'cosine' => $cosine,
  168 + 'similarity' => json_encode($similarity, true),
168 'created_at'=>date('Y-m-d H:i:s'), 169 'created_at'=>date('Y-m-d H:i:s'),
169 'updated_at'=>date('Y-m-d H:i:s'), 170 'updated_at'=>date('Y-m-d H:i:s'),
170 ]; 171 ];
@@ -315,17 +316,6 @@ class GeoQuestionRes extends Command @@ -315,17 +316,6 @@ class GeoQuestionRes extends Command
315 } 316 }
316 317
317 /** 318 /**
318 - * @remark :预期结果对比  
319 - * @name :getExpectResult  
320 - * @author :lyh  
321 - * @method :post  
322 - * @time :2025/8/12 13:51  
323 - */  
324 - public function getExpectResult($question,$answer,$expect){  
325 - $str = "客户提出的问题:{$question},客户得到的回复:{$answer},客户需要预期:{$expect},请分析得到的回复和预期是否一致,仅回复我是或者否";  
326 - }  
327 -  
328 - /**  
329 * 获取待执行任务ID 319 * 获取待执行任务ID
330 * @return mixed 320 * @return mixed
331 */ 321 */
@@ -33,6 +33,7 @@ class CreateProject extends Command @@ -33,6 +33,7 @@ class CreateProject extends Command
33 protected $description = '创建项目'; 33 protected $description = '创建项目';
34 34
35 public function handle(){ 35 public function handle(){
  36 + dd(1);
36 return $this->sync(); 37 return $this->sync();
37 } 38 }
38 39
@@ -42,10 +43,12 @@ class CreateProject extends Command @@ -42,10 +43,12 @@ class CreateProject extends Command
42 * @throws \Exception 43 * @throws \Exception
43 */ 44 */
44 public function sync($is_update = 0){ 45 public function sync($is_update = 0){
45 - $company = '济南市莱芜凤城铝合金有限公司';  
46 - $mobile = '13806340552';  
47 - $plan = '标准版';  
48 - $cooperate_date = '2019-11-19'; 46 + $company = '山东临磨数控机床装备有限公司(自建站)';
  47 + $mobile = '18663004388';
  48 + $lead_name = '18663004388';
  49 + $plan = '商务版';
  50 + $cooperate_date = '2025-08-21';
  51 +// $channel = '{"user_id": "732", "zone_id": "1", "channel_id": "95"}';
49 $channel = '{"user_id": "1989", "zone_id": "4", "channel_id": "13"}'; 52 $channel = '{"user_id": "1989", "zone_id": "4", "channel_id": "13"}';
50 53
51 $title = date('Ymd') . '-' . $company; 54 $title = date('Ymd') . '-' . $company;
@@ -53,7 +56,7 @@ class CreateProject extends Command @@ -53,7 +56,7 @@ class CreateProject extends Command
53 'project'=>[ 56 'project'=>[
54 'title' => $title, 57 'title' => $title,
55 'company' => $company, 58 'company' => $company,
56 - 'lead_name' => $mobile, 59 + 'lead_name' => $lead_name,
57 'mobile' => $mobile, 60 'mobile' => $mobile,
58 'mysql_id'=>Project::MYSQL_ID, 61 'mysql_id'=>Project::MYSQL_ID,
59 'serve_id'=>9, 62 'serve_id'=>9,
@@ -61,7 +64,7 @@ class CreateProject extends Command @@ -61,7 +64,7 @@ class CreateProject extends Command
61 'channel' => $channel, 64 'channel' => $channel,
62 'requirement' => '', 65 'requirement' => '',
63 'cooperate_date' => $cooperate_date, 66 'cooperate_date' => $cooperate_date,
64 - 'from_order_id' => '', 67 + 'from_order_id' => uniqid(),
65 'type' => $is_update, 68 'type' => $is_update,
66 'is_upgrade'=>$is_update, 69 'is_upgrade'=>$is_update,
67 ], 70 ],
@@ -101,6 +101,19 @@ class SyncProject extends Command @@ -101,6 +101,19 @@ class SyncProject extends Command
101 if($data['data']['order_type'] == '续费'){ 101 if($data['data']['order_type'] == '续费'){
102 $this->renewSync($data['data']); 102 $this->renewSync($data['data']);
103 } 103 }
  104 + // TODO 如果是续费项目 并且有GEO版本,需要处理GEO版本
  105 + if (($data['data']['order_type'] == '续费') && !empty($data['data']['geo_plan']) && ($data['data']['geo_plan'] != '无')) {
  106 + // 续费单,并且有GEO版本, 正常版本不创建 初始化正常版本
  107 + $data['data']['plan_marketing'] = '无';
  108 + //创建对应的GEO版本
  109 + $projectModel = new Project();
  110 + $seo_plan = $this->versionSeoData($data['data']['geo_plan'] ?? '');
  111 + $projectInfo = $projectModel->leftJoin('gl_project_deploy_build', 'gl_project.id', '=', 'gl_project_deploy_build.project_id')->where('gl_project.company', $data['data']['company_name'])->where('gl_project_deploy_build.seo_plan',$seo_plan)->select(['gl_project.id AS id'])->first();
  112 + if (empty($projectInfo)) {
  113 + // 创建对应GEO项目
  114 + $this->sync($data['data'],$is_update);
  115 + }
  116 + }
104 $item->status = NoticeLog::STATUS_SUCCESS; 117 $item->status = NoticeLog::STATUS_SUCCESS;
105 $item->save(); 118 $item->save();
106 echo 'success:' . $item['id'] . '执行时间:' . date('Y-m-d H:i:s') . PHP_EOL; 119 echo 'success:' . $item['id'] . '执行时间:' . date('Y-m-d H:i:s') . PHP_EOL;
@@ -136,7 +149,7 @@ class SyncProject extends Command @@ -136,7 +149,7 @@ class SyncProject extends Command
136 * @time :2023/8/11 15:33 149 * @time :2023/8/11 15:33
137 */ 150 */
138 public function renewSync($param){ 151 public function renewSync($param){
139 - $title = date('Ymd') . '-' . $param['company_name'];; 152 + $title = date('Ymd') . '-' . $param['company_name'];
140 $data = [ 153 $data = [
141 'title' => '【续费单】'.$title, 154 'title' => '【续费单】'.$title,
142 'company' => $param['company_name'], 155 'company' => $param['company_name'],
@@ -146,7 +159,7 @@ class SyncProject extends Command @@ -146,7 +159,7 @@ class SyncProject extends Command
146 'channel' => json_encode(Channel::getProjectChannel($param['company_id'], $param['username_sales'])), 159 'channel' => json_encode(Channel::getProjectChannel($param['company_id'], $param['username_sales'])),
147 'requirement' => $param['remark'], 160 'requirement' => $param['remark'],
148 'cooperate_date' => date('Y-m-d', $param['create_time']), 161 'cooperate_date' => date('Y-m-d', $param['create_time']),
149 -// 'api_no' => $param['id'], //改手动填 162 + 'api_no' => $param['id'], //改手动填
150 'amount' => $param['plan_price'], 163 'amount' => $param['plan_price'],
151 'contract' => json_encode($param['files']), 164 'contract' => json_encode($param['files']),
152 'bill' => json_encode($param['images']), 165 'bill' => json_encode($param['images']),
@@ -32,60 +32,29 @@ class SyncTimeFiles extends Command @@ -32,60 +32,29 @@ class SyncTimeFiles extends Command
32 { 32 {
33 $fileModel = new File(); 33 $fileModel = new File();
34 // $imagesModel = new Image(); 34 // $imagesModel = new Image();
35 - $start = '2024-11-07 15:00:00';  
36 - $end = '2024-11-07 15:25:00'; 35 + $start = '2025-08-20 00:00:00';
  36 + $end = '2025-08-28 00:00:00';
37 $lists = $fileModel->list(['created_at'=>['between',[$start,$end]]]); 37 $lists = $fileModel->list(['created_at'=>['between',[$start,$end]]]);
38 foreach ($lists as $v){ 38 foreach ($lists as $v){
39 $path = $v['path']; 39 $path = $v['path'];
40 - $this->param['name'] = basename($path);  
41 - $this->param['path'] = str_replace('/'.$this->param['name'],'',$path);  
42 - $file_path = $this->getUrl($this->param['path'].'/'.$this->param['name'], 0,0);  
43 - $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$this->param['path'].'" https://v6-file.globalso.com/upload.php';  
44 - echo date('Y-m-d H:i:s') . ' | ' . $cmd . PHP_EOL;  
45 - $code = shell_exec($cmd); 40 + echo date('Y-m-d H:i:s') . ' | 图片链接:' . $path . PHP_EOL;
  41 + $code = $this->synchronizationFile($path);
46 if(200 != (int)$code){ 42 if(200 != (int)$code){
47 echo date('Y-m-d H:i:s') . ' | 错误状态:' . $code . PHP_EOL; 43 echo date('Y-m-d H:i:s') . ' | 错误状态:' . $code . PHP_EOL;
48 -// $errorFileModel = new ErrorFile();  
49 -// $errorFileModel->add(['path'=>$this->param['path'].'/'.$this->param['name']]); 44 + $errorFileModel = new ErrorFile();
  45 + $errorFileModel->add(['path'=>$this->param['path'].'/'.$this->param['name']]);
50 } 46 }
51 echo date('Y-m-d H:i:s') . ' | ok:' . $code . PHP_EOL; 47 echo date('Y-m-d H:i:s') . ' | ok:' . $code . PHP_EOL;
52 } 48 }
53 return true; 49 return true;
54 } 50 }
55 51
56 - /**  
57 - * @remark :获取图片文件链接  
58 - * @name :getUrl  
59 - * @author :lyh  
60 - * @method :post  
61 - * @time :2024/5/22 11:53  
62 - */  
63 - public function getUrl($path,$storage_type,$location){  
64 - if(is_array($path)){  
65 - $url =[];  
66 - foreach ($path as $v){  
67 - $url[] = $this->getUrl($v,$storage_type,$location);  
68 - }  
69 - }else{  
70 - if(empty($path)){  
71 - return '';  
72 - }  
73 - if((strpos($path,'https://')!== false) || (strpos($path,'http://') !== false)){  
74 - return $path;  
75 - }  
76 - if(substr($path,0,2) == '//'){  
77 - return 'https:'.$path;  
78 - }  
79 - if($location == 0){  
80 - $cos = config('filesystems.disks.cos');  
81 - $cosCdn = ($storage_type == 0) ? $cos['cdn'] : $cos['cdn1'];  
82 - $url = $cosCdn.$path;  
83 - }else{  
84 - $s3 = config('filesystems.disks.s3');  
85 - $cdn = $s3['cdn'];  
86 - $url = $cdn.$path;  
87 - }  
88 - }  
89 - return $url; 52 + public function synchronizationFile($path_name){
  53 + //同步到大文件
  54 + $file_path = config('filesystems.disks.cos')['cdn1'].$path_name;
  55 + $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME);
  56 + $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$directoryPath.'" https://v6-file.globalso.com/upload.php';
  57 + return shell_exec($cmd);
90 } 58 }
  59 +
91 } 60 }
@@ -47,16 +47,11 @@ class SyncTimeMinuteFile extends Command @@ -47,16 +47,11 @@ class SyncTimeMinuteFile extends Command
47 } 47 }
48 foreach ($lists as $v){ 48 foreach ($lists as $v){
49 $path = $v['path']; 49 $path = $v['path'];
50 - if (file_exists($dir.$path)) {  
51 - echo date('Y-m-d H:i:s') . ' | file_ok:' . $dir.$path . PHP_EOL;  
52 - continue;  
53 - }  
54 - $this->param['name'] = basename($path);  
55 - $this->param['path'] = str_replace('/'.$this->param['name'],'',$path);  
56 - $file_path = $this->getUrl($this->param['path'].'/'.$this->param['name'], 0,0);  
57 - $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$this->param['path'].'" https://v6-file.globalso.com/upload.php';  
58 - echo date('Y-m-d H:i:s') . ' | ' . $cmd . PHP_EOL;  
59 - $code = shell_exec($cmd); 50 +// if (file_exists($dir.$path)) {
  51 +// echo date('Y-m-d H:i:s') . ' | file_ok:' . $dir.$path . PHP_EOL;
  52 +// continue;
  53 +// }
  54 + $code = $this->synchronizationFile($path);
60 if(200 != (int)$code){ 55 if(200 != (int)$code){
61 echo date('Y-m-d H:i:s') . ' | 错误状态:' . $code . PHP_EOL; 56 echo date('Y-m-d H:i:s') . ' | 错误状态:' . $code . PHP_EOL;
62 $errorFileModel = new ErrorFile(); 57 $errorFileModel = new ErrorFile();
@@ -67,6 +62,14 @@ class SyncTimeMinuteFile extends Command @@ -67,6 +62,14 @@ class SyncTimeMinuteFile extends Command
67 return true; 62 return true;
68 } 63 }
69 64
  65 + public function synchronizationFile($path_name){
  66 + //同步到大文件
  67 + $file_path = config('filesystems.disks.cos')['cdn1'].$path_name;
  68 + $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';
  70 + return shell_exec($cmd);
  71 + }
  72 +
70 /** 73 /**
71 * @remark :获取图片文件链接 74 * @remark :获取图片文件链接
72 * @name :getUrl 75 * @name :getUrl
@@ -30,12 +30,7 @@ class SyncVideo extends Command @@ -30,12 +30,7 @@ class SyncVideo extends Command
30 public function handle() 30 public function handle()
31 { 31 {
32 $path = $this->argument('path'); 32 $path = $this->argument('path');
33 - $this->param['name'] = basename($path);  
34 - $this->param['path'] = str_replace('/'.$this->param['name'],'',$path);  
35 - $file_path = $this->getUrl($this->param['path'].'/'.$this->param['name'], 0,0);  
36 - $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$this->param['path'].'" https://v6-file.globalso.com/upload.php';  
37 - echo date('Y-m-d H:i:s') . ' | ' . $cmd . PHP_EOL;  
38 - $code = shell_exec($cmd); 33 + $code = $this->synchronizationFile($path);
39 echo date('Y-m-d H:i:s') . ' | ' . $code . PHP_EOL; 34 echo date('Y-m-d H:i:s') . ' | ' . $code . PHP_EOL;
40 if(200 != (int)$code){ 35 if(200 != (int)$code){
41 echo date('Y-m-d H:i:s') . ' | ' . $code . PHP_EOL; 36 echo date('Y-m-d H:i:s') . ' | ' . $code . PHP_EOL;
@@ -45,6 +40,14 @@ class SyncVideo extends Command @@ -45,6 +40,14 @@ class SyncVideo extends Command
45 return true; 40 return true;
46 } 41 }
47 42
  43 + public function synchronizationFile($path_name){
  44 + //同步到大文件
  45 + $file_path = config('filesystems.disks.cos')['cdn1'].$path_name;
  46 + $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';
  48 + return shell_exec($cmd);
  49 + }
  50 +
48 /** 51 /**
49 * @remark :获取图片文件链接 52 * @remark :获取图片文件链接
50 * @name :getUrl 53 * @name :getUrl
@@ -199,7 +199,7 @@ class TicketCount extends Command @@ -199,7 +199,7 @@ class TicketCount extends Command
199 ) 199 )
200 ->groupBy('p.project_cate') 200 ->groupBy('p.project_cate')
201 ->pluck('ticket_count', 'project_cate'); 201 ->pluck('ticket_count', 'project_cate');
202 - $timeout_num = $ticketModel->counts(['end_at'=>null,'plan_end_at'=>['>',date('Y-m-d H:i:s')]]); 202 + $timeout_num = $ticketModel->counts(['plan_end_at'=>['>',date('Y-m-d H:i:s')]]);
203 $timeout_ratio = null; 203 $timeout_ratio = null;
204 if(!empty($timeout_num)){ 204 if(!empty($timeout_num)){
205 $timeout_ratio = round($timeout_num / $ticket_num, 3); 205 $timeout_ratio = round($timeout_num / $ticket_num, 3);
@@ -60,7 +60,29 @@ class FetchTicketProjects extends Command @@ -60,7 +60,29 @@ class FetchTicketProjects extends Command
60 $postids = []; 60 $postids = [];
61 61
62 while (true) { 62 while (true) {
63 - $response = Http::get('https://www.quanqiusou.cn/extend_api/webs/globalso_all.php?page=' . $page); 63 + try {
  64 + $maxRetries = 3;
  65 + $retryCount = 0;
  66 +
  67 + while ($retryCount < $maxRetries) {
  68 + try {
  69 + $response = Http::get('https://www.quanqiusou.cn/extend_api/webs/globalso_all.php?page=' . $page);
  70 + break; // 如果请求成功,跳出重试循环
  71 + } catch (\Exception $e) {
  72 + $retryCount++;
  73 + if ($retryCount >= $maxRetries) {
  74 + // 如果达到最大重试次数,抛出异常
  75 + throw $e;
  76 + }
  77 + // 等待一段时间再重试
  78 + sleep(2);
  79 + }
  80 + }
  81 + }catch (\Exception $e){
  82 + echo now() . " | ERROR | " . $e->getMessage() . "\n" . $e->getTraceAsString() . "\n";
  83 + break;
  84 + }
  85 +
64 if ($response->status() == 200) { 86 if ($response->status() == 200) {
65 $resp_json = $response->json(); 87 $resp_json = $response->json();
66 $items = $resp_json['data'] ?? []; 88 $items = $resp_json['data'] ?? [];
@@ -200,6 +200,7 @@ class OptimizeController extends BaseController @@ -200,6 +200,7 @@ class OptimizeController extends BaseController
200 'gl_project.is_translate AS is_translate', 200 'gl_project.is_translate AS is_translate',
201 'gl_project.is_translate_tag AS is_translate_tag', 201 'gl_project.is_translate_tag AS is_translate_tag',
202 'gl_project.is_upgrade AS is_upgrade', 202 'gl_project.is_upgrade AS is_upgrade',
  203 + 'gl_project.project_type AS project_type',
203 'gl_project.site_status AS site_status', 204 'gl_project.site_status AS site_status',
204 'gl_project_online_check.id AS online_check_id', 205 'gl_project_online_check.id AS online_check_id',
205 'gl_project_online_check.question AS question', 206 'gl_project_online_check.question AS question',
@@ -161,6 +161,7 @@ class RenewProjectController extends BaseController @@ -161,6 +161,7 @@ class RenewProjectController extends BaseController
161 $data = APublicModel::getNumByProjectId($item['id']); 161 $data = APublicModel::getNumByProjectId($item['id']);
162 } 162 }
163 $plan = Project::planMap(); 163 $plan = Project::planMap();
  164 + $seoPlan = Project::seoMap();
164 $item = [ 165 $item = [
165 'id' => $item['id'], 166 'id' => $item['id'],
166 'title' => $item['title'], 167 'title' => $item['title'],
@@ -178,8 +179,10 @@ class RenewProjectController extends BaseController @@ -178,8 +179,10 @@ class RenewProjectController extends BaseController
178 'optimize_tech' => $manageModel->getName($item['deploy_optimize']['tech_mid']), //售后技术 179 'optimize_tech' => $manageModel->getName($item['deploy_optimize']['tech_mid']), //售后技术
179 'type' => $item['type'], 180 'type' => $item['type'],
180 'test_domain' => $item['deploy_build']['test_domain'] ?? 0, 181 'test_domain' => $item['deploy_build']['test_domain'] ?? 0,
181 - 'plan' =>$plan[$item['deploy_build']['plan']] ?? '白帽seo版本', 182 + 'plan' =>$plan[$item['deploy_build']['plan']] ?? '无',
  183 + 'seo_plan' =>$seoPlan[$item['deploy_build']['seo_plan']] ?? '无',
182 'plan_id' =>$item['deploy_build']['plan'], 184 'plan_id' =>$item['deploy_build']['plan'],
  185 + 'seo_plan_id' =>$item['deploy_build']['seo_plan'],
183 'domain' => !empty($item['deploy_optimize']['domain']) ? $domainModel->getDomain($item['deploy_optimize']['domain']) : '', 186 'domain' => !empty($item['deploy_optimize']['domain']) ? $domainModel->getDomain($item['deploy_optimize']['domain']) : '',
184 'created_at' => date('Y年m月d日', strtotime($item['created_at'])), 187 'created_at' => date('Y年m月d日', strtotime($item['created_at'])),
185 'autologin_code' => getAutoLoginCode($item['id']), 188 'autologin_code' => getAutoLoginCode($item['id']),
@@ -6,6 +6,7 @@ use App\Enums\Common\Code; @@ -6,6 +6,7 @@ use App\Enums\Common\Code;
6 use App\Http\Controllers\Aside\BaseController; 6 use App\Http\Controllers\Aside\BaseController;
7 use App\Http\Logic\Aside\Template\ATemplateLogic; 7 use App\Http\Logic\Aside\Template\ATemplateLogic;
8 use App\Http\Requests\Aside\Template\ATemplateRequest; 8 use App\Http\Requests\Aside\Template\ATemplateRequest;
  9 +use App\Models\Manage\Manage;
9 use App\Models\Template\TemplateLabel; 10 use App\Models\Template\TemplateLabel;
10 11
11 /** 12 /**
@@ -26,12 +27,14 @@ class ATemplateController extends BaseController @@ -26,12 +27,14 @@ class ATemplateController extends BaseController
26 public function lists(ATemplateLogic $aTemplateLogic){ 27 public function lists(ATemplateLogic $aTemplateLogic){
27 $templateLabel = new TemplateLabel(); 28 $templateLabel = new TemplateLabel();
28 $this->map = $this->searchLabelName($templateLabel); 29 $this->map = $this->searchLabelName($templateLabel);
29 - $filed = ['id','name','image','url','status','sort','deleted_status','test_model','created_at','project_id']; 30 + $filed = ['id','name','image','url','status','upload_id','sort','deleted_status','test_model','created_at','project_id'];
30 $lists = $aTemplateLogic->aTemplateList($this->map,$this->page,$this->row,$this->order,$filed); 31 $lists = $aTemplateLogic->aTemplateList($this->map,$this->page,$this->row,$this->order,$filed);
31 if(!empty($lists) && !empty($lists['list'])){ 32 if(!empty($lists) && !empty($lists['list'])){
  33 + $manageModel = new Manage();
32 foreach ($lists['list'] as $k => $v){ 34 foreach ($lists['list'] as $k => $v){
33 $v['label'] = $templateLabel->list(['template_id'=>$v['id'],'type'=>1],'id',['id','name'],'desc',5); 35 $v['label'] = $templateLabel->list(['template_id'=>$v['id'],'type'=>1],'id',['id','name'],'desc',5);
34 $v['image_link'] = getImageUrl($v['image']); 36 $v['image_link'] = getImageUrl($v['image']);
  37 + $v['upload_name'] = $manageModel->getName($v['upload_id']);
35 $lists['list'][$k] = $v; 38 $lists['list'][$k] = $v;
36 } 39 }
37 } 40 }
@@ -89,6 +89,9 @@ class AsideTicketController extends BaseController @@ -89,6 +89,9 @@ class AsideTicketController extends BaseController
89 $q->whereIn('engineer_id', $manageIdArr); 89 $q->whereIn('engineer_id', $manageIdArr);
90 }); 90 });
91 } 91 }
  92 + if(!empty($this->param['start_at']) && !empty($this->param['end_at'])){
  93 + return $query->whereBetween('created_at',[$this->param['start_at'],$this->param['end_at']]);
  94 + }
92 // 添加排序功能 95 // 添加排序功能
93 $query->orderBy('status', 'asc'); 96 $query->orderBy('status', 'asc');
94 // $query->orderBy('id', 'desc'); 97 // $query->orderBy('id', 'desc');
@@ -472,7 +472,9 @@ class ProjectLogic extends BaseLogic @@ -472,7 +472,9 @@ class ProjectLogic extends BaseLogic
472 } 472 }
473 $param['confirm_file'] = Arr::a2s($param['confirm_file'] ?? []); 473 $param['confirm_file'] = Arr::a2s($param['confirm_file'] ?? []);
474 $remain_day = $param['deploy_build']['service_duration'] - $param['finish_remain_day']; 474 $remain_day = $param['deploy_build']['service_duration'] - $param['finish_remain_day'];
  475 + $seo_remain_day = $param['deploy_build']['seo_service_duration'] - $param['bm_finish_remain_day'];
475 $param['remain_day'] = ($remain_day > 0) ? $remain_day : 0; 476 $param['remain_day'] = ($remain_day > 0) ? $remain_day : 0;
  477 + $param['seo_remain_day'] = ($seo_remain_day > 0) ? $seo_remain_day : 0;
476 //文件上传默认值 478 //文件上传默认值
477 if($param['is_upload_manage']){ 479 if($param['is_upload_manage']){
478 $param['upload_config'] = [ 480 $param['upload_config'] = [
@@ -42,7 +42,7 @@ class TicketLogic extends BaseLogic @@ -42,7 +42,7 @@ class TicketLogic extends BaseLogic
42 $date = date('Y-m-d');//今日时间 42 $date = date('Y-m-d');//今日时间
43 $data['add_num'] = $ticketModel->counts(['created_at'=>['between',[$date.' 00:00:00',$date.' 23:59:59']]]);//今日新增工单 43 $data['add_num'] = $ticketModel->counts(['created_at'=>['between',[$date.' 00:00:00',$date.' 23:59:59']]]);//今日新增工单
44 $data['processed_num'] = $ticketModel->counts(['end_at'=>['between',[$date.' 00:00:00',$date.' 23:59:59']]]);//今日已处理工单 44 $data['processed_num'] = $ticketModel->counts(['end_at'=>['between',[$date.' 00:00:00',$date.' 23:59:59']]]);//今日已处理工单
45 - $data['untreated_num'] = $ticketModel->counts(['end_at'=>null]);//今日未处理工单 45 + $data['untreated_num'] = $ticketModel->counts(['end_at'=>null,'plan_end_at'=>['like','%'.date('Y-m-d').'%']]);//今日未处理工单
46 $submit_a_side = $ticketModel->formatQuery(['submit_side'=>1])->sum('submit_side'); 46 $submit_a_side = $ticketModel->formatQuery(['submit_side'=>1])->sum('submit_side');
47 $submit_b_side = $ticketModel->formatQuery(['submit_side'=>2])->sum('submit_side'); 47 $submit_b_side = $ticketModel->formatQuery(['submit_side'=>2])->sum('submit_side');
48 $data['source'] = ['a'=>$submit_a_side,'b'=>$submit_b_side]; 48 $data['source'] = ['a'=>$submit_a_side,'b'=>$submit_b_side];
@@ -48,7 +48,7 @@ class GeoQuestionResLogic extends BaseLogic @@ -48,7 +48,7 @@ class GeoQuestionResLogic extends BaseLogic
48 */ 48 */
49 public function getResultList($map = [],$page = 1,$row = 20){ 49 public function getResultList($map = [],$page = 1,$row = 20){
50 $map['project_id'] = $this->user['project_id']; 50 $map['project_id'] = $this->user['project_id'];
51 - $filed = ['id','project_id','question_id','platform','is_match','question','en_question','keywords','url','label','created_at','updated_at']; 51 + $filed = ['id','project_id','question_id','platform','is_match','question','en_question','keywords','url','label','cosine','created_at','updated_at'];
52 if(!empty($map['created_at'])){ 52 if(!empty($map['created_at'])){
53 $map['created_at'] = ['between',[$map['created_at'].' 00:00:00',$map['created_at'].' 23:59:59']]; 53 $map['created_at'] = ['between',[$map['created_at'].' 00:00:00',$map['created_at'].' 23:59:59']];
54 $this->model = new GeoQuestionLog(); 54 $this->model = new GeoQuestionLog();
@@ -93,32 +93,50 @@ class GeoQuestionResLogic extends BaseLogic @@ -93,32 +93,50 @@ class GeoQuestionResLogic extends BaseLogic
93 $core_question_count = $questionTotalCount = $urlTotalCount = $keywordsTotalCount = 0; 93 $core_question_count = $questionTotalCount = $urlTotalCount = $keywordsTotalCount = 0;
94 $keywordArr = []; 94 $keywordArr = [];
95 $questionLogModel = new GeoQuestionLog(); 95 $questionLogModel = new GeoQuestionLog();
96 - $keywordUrlCount = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'hit'=>['!=',0]]);  
97 - $coreKeywordUrlCount = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'label'=>['like','%核心问题%'],'hit'=>['!=',0]]);  
98 - foreach ($list as $item){  
99 - $questionTotalCount += count($item['question'] ?? []);  
100 - //核心问题数  
101 - if(strpos($item['label'],'核心问题') !== false){  
102 - $core_question_count += count($item['question'] ?? []); 96 + if($this->user['project_id'] == 4533){
  97 + $keywordUrlCount = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'is_match'=>1,'hit'=>['!=',0]]);
  98 + foreach ($list as $item){
  99 + $questionTotalCount += count($item['question'] ?? []);
  100 + //核心问题数
  101 + if(strpos($item['label'],'核心问题') !== false){
  102 + $core_question_count += count($item['question'] ?? []);
  103 + }
  104 + foreach ($item['keywords'] as $keyWordItem){
  105 + if (!array_key_exists($keyWordItem, $keywordArr)) {
  106 + $keywordArr[$keyWordItem] = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'is_match'=>1,'keywords'=>['like','%"'.$keyWordItem.'"%']]);
  107 + }
  108 + }
103 } 109 }
104 - $keywordsTotalCount += count($item['keywords'] ?? []);  
105 - $urlTotalCount += count($item['url'] ?? []);  
106 - foreach ($item['keywords'] as $keyWordItem){  
107 - if (!array_key_exists($keyWordItem, $keywordArr)) {  
108 - $keywordArr[$keyWordItem] = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'keywords'=>['like','%"'.$keyWordItem.'"%']]); 110 + $coreKeywordUrlCount = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'label'=>['like','%核心问题%'],'is_match'=>1,'hit'=>['!=',0]]);
  111 + $data = [
  112 + 'question_count'=>$questionTotalCount,//问题总数
  113 + 'core_question_count'=>$core_question_count,//核心问题总数
  114 + 'keywords_url_count'=>$keywordUrlCount,
  115 + 'keywords_arr' => $keywordArr,
  116 + 'core_keyword_url_count'=>$coreKeywordUrlCount ?? 0
  117 + ];
  118 + return $this->success($data);
  119 + }else{
  120 + $keywordUrlCount = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'hit'=>['!=',0]]);
  121 + foreach ($list as $item){
  122 + $questionTotalCount += count($item['question'] ?? []);
  123 + $keywordsTotalCount += count($item['keywords'] ?? []);
  124 + $urlTotalCount += count($item['url'] ?? []);
  125 + foreach ($item['keywords'] as $keyWordItem){
  126 + if (!array_key_exists($keyWordItem, $keywordArr)) {
  127 + $keywordArr[$keyWordItem] = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'keywords'=>['like','%"'.$keyWordItem.'"%']]);
  128 + }
109 } 129 }
110 } 130 }
  131 + $data = [
  132 + 'question_count'=>$questionTotalCount,
  133 + 'keywords_count'=>$keywordsTotalCount,
  134 + 'url_count'=>$urlTotalCount,
  135 + 'keywords_url_count'=>$keywordUrlCount,
  136 + 'keywords_arr' => $keywordArr,
  137 + ];
  138 + return $this->success($data);
111 } 139 }
112 - $data = [  
113 - 'keywords_count'=>$keywordsTotalCount,  
114 - 'url_count'=>$urlTotalCount,  
115 - 'question_count'=>$questionTotalCount,  
116 - 'keywords_url_count'=>$keywordUrlCount,  
117 - 'keywords_arr' => $keywordArr,  
118 - 'core_question_count'=>$core_question_count,  
119 - 'core_keyword_url_count'=>$coreKeywordUrlCount  
120 - ];  
121 - return $this->success($data);  
122 } 140 }
123 141
124 /** 142 /**
@@ -134,7 +152,11 @@ class GeoQuestionResLogic extends BaseLogic @@ -134,7 +152,11 @@ class GeoQuestionResLogic extends BaseLogic
134 $list = $platformModel->list(['status'=>1],'id',['name','en_name']); 152 $list = $platformModel->list(['status'=>1],'id',['name','en_name']);
135 $questionResModel = new GeoQuestionLog(); 153 $questionResModel = new GeoQuestionLog();
136 foreach ($list as $item){ 154 foreach ($list as $item){
137 - $data[$item['name']] = $questionResModel->counts(['project_id'=>$this->user['project_id'],'hit'=>['!=',0],'platform'=>$item['en_name']]); 155 + if($this->user['project_id'] == 4533){
  156 + $data[$item['name']] = $questionResModel->counts(['project_id'=>$this->user['project_id'],'is_match'=>1,'hit'=>['!=',0],'platform'=>$item['en_name']]);
  157 + }else{
  158 + $data[$item['name']] = $questionResModel->counts(['project_id'=>$this->user['project_id'],'hit'=>['!=',0],'platform'=>$item['en_name']]);
  159 + }
138 } 160 }
139 return $this->success($data); 161 return $this->success($data);
140 } 162 }
@@ -34,10 +34,8 @@ class SyncImageFileJob implements ShouldQueue @@ -34,10 +34,8 @@ class SyncImageFileJob implements ShouldQueue
34 */ 34 */
35 public function handle() 35 public function handle()
36 { 36 {
37 - $file_path = $this->getUrl($this->param['path'].'/'.$this->param['name'], 0,$this->param['location']);  
38 - $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$this->param['path'].'" https://v6-file.globalso.com/upload.php';  
39 - echo date('Y-m-d H:i:s') . ' | ' . $cmd . PHP_EOL;  
40 - $code = shell_exec($cmd); 37 + $code = $this->synchronizationFile($this->param['path'].'/'.$this->param['name']);
  38 + echo date('Y-m-d H:i:s') . ' | ' . $code . PHP_EOL;
41 if(200 != (int)$code){ 39 if(200 != (int)$code){
42 $errorFileModel = new ErrorFile(); 40 $errorFileModel = new ErrorFile();
43 $errorFileModel->add(['path'=>$this->param['path'].'/'.$this->param['name']]); 41 $errorFileModel->add(['path'=>$this->param['path'].'/'.$this->param['name']]);
@@ -45,39 +43,12 @@ class SyncImageFileJob implements ShouldQueue @@ -45,39 +43,12 @@ class SyncImageFileJob implements ShouldQueue
45 return true; 43 return true;
46 } 44 }
47 45
48 - /**  
49 - * @remark :获取图片文件链接  
50 - * @name :getUrl  
51 - * @author :lyh  
52 - * @method :post  
53 - * @time :2024/5/22 11:53  
54 - */  
55 - public function getUrl($path,$storage_type,$location){  
56 - if(is_array($path)){  
57 - $url =[];  
58 - foreach ($path as $v){  
59 - $url[] = $this->getUrl($v,$storage_type,$location);  
60 - }  
61 - }else{  
62 - if(empty($path)){  
63 - return '';  
64 - }  
65 - if((strpos($path,'https://')!== false) || (strpos($path,'http://') !== false)){  
66 - return $path;  
67 - }  
68 - if(substr($path,0,2) == '//'){  
69 - return 'https:'.$path;  
70 - }  
71 - if($location == 0){  
72 - $cos = config('filesystems.disks.cos');  
73 - $cosCdn = ($storage_type == 0) ? $cos['cdn'] : $cos['cdn1'];  
74 - $url = $cosCdn.$path;  
75 - }else{  
76 - $s3 = config('filesystems.disks.s3');  
77 - $cdn = $s3['cdn'];  
78 - $url = $cdn.$path;  
79 - }  
80 - }  
81 - return $url; 46 + public function synchronizationFile($path_name){
  47 + //同步到大文件
  48 + $file_path = config('filesystems.disks.cos')['cdn1'].$path_name;
  49 + $directoryPath = pathinfo($path_name, PATHINFO_DIRNAME);
  50 + $cmd = 'curl -k -F "file_path='.$file_path.'" -F "save_path=/www/wwwroot/cos'.$directoryPath.'" https://v6-file.globalso.com/upload.php';
  51 + echo date('Y-m-d H:i:s') . ' | ' . $cmd . PHP_EOL;
  52 + return shell_exec($cmd);
82 } 53 }
83 } 54 }
@@ -79,6 +79,7 @@ class Project extends Base @@ -79,6 +79,7 @@ class Project extends Base
79 3=>'2-4', 79 3=>'2-4',
80 4=>'3-5', 80 4=>'3-5',
81 5=>'5-7', 81 5=>'5-7',
  82 + 6=>'1/2'
82 ]; 83 ];
83 if($val){ 84 if($val){
84 return $arr[$val] ?? ''; 85 return $arr[$val] ?? '';
@@ -9,6 +9,8 @@ @@ -9,6 +9,8 @@
9 9
10 namespace App\Services\Geo; 10 namespace App\Services\Geo;
11 11
  12 +use Illuminate\Support\Facades\Http;
  13 +
12 class GeoService 14 class GeoService
13 { 15 {
14 public $api_key = 'UkzZljFv83Z2qBi5YR1o3f2otAVWtug6'; 16 public $api_key = 'UkzZljFv83Z2qBi5YR1o3f2otAVWtug6';
@@ -108,4 +110,31 @@ class GeoService @@ -108,4 +110,31 @@ class GeoService
108 $data = http_post($url,json_encode($message,true),$header); 110 $data = http_post($url,json_encode($message,true),$header);
109 return $data; 111 return $data;
110 } 112 }
  113 +
  114 + /**
  115 + * 获取语句余弦相似度
  116 + * $text 会被拆解语句, 分析预警传$text
  117 + * @param string $standard 标准答案
  118 + * @param string $text 需要分析的语句
  119 + * @param string $embedding_model
  120 + * @param string $similarity_method
  121 + * @return \Illuminate\Http\Client\Response
  122 + */
  123 + public function cosineSimilarity($standard, $text, $embedding_model = 'text-embedding-3-small', $similarity_method = 'cosine')
  124 + {
  125 + $url = 'http://knowledge_base.zabbix.waimaoq.com/v1/crud/split_similarity';
  126 + $header = [
  127 + 'accept: application/json',
  128 + 'Content-Type: application/json'
  129 + ];
  130 + $param = [
  131 + 'text1' => $standard,
  132 + 'text2' => $text,
  133 + 'embedding_model' => $embedding_model,
  134 + 'similarity_method' => $similarity_method
  135 + ];
  136 +
  137 + $result = Http::post($url, $param);
  138 + return $result->json();
  139 + }
111 } 140 }