作者 刘锟

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

@@ -40,8 +40,8 @@ class AiBlogTask extends Command @@ -40,8 +40,8 @@ class AiBlogTask extends Command
40 protected $signature = 'save_ai_blog'; 40 protected $signature = 'save_ai_blog';
41 41
42 public $updateProject = [];//需更新的列表 42 public $updateProject = [];//需更新的列表
43 -  
44 - 43 + public $projectSetting = [];
  44 + public $routes = [];//需要更新的路由
45 45
46 /** 46 /**
47 * The console command description. 47 * The console command description.
@@ -50,10 +50,14 @@ class AiBlogTask extends Command @@ -50,10 +50,14 @@ class AiBlogTask extends Command
50 */ 50 */
51 protected $description = '查询ai_blog是否已经生成'; 51 protected $description = '查询ai_blog是否已经生成';
52 52
  53 + /**
  54 + * @return bool
  55 + * @throws \Exception
  56 + */
53 public function handle(){ 57 public function handle(){
54 while (true){ 58 while (true){
55 //获取任务id 59 //获取任务id
56 - $task_id = $this->getTaskId(2); 60 + $task_id = $this->getTaskId();
57 if(empty($task_id)){ 61 if(empty($task_id)){
58 sleep(300); 62 sleep(300);
59 continue; 63 continue;
@@ -64,16 +68,15 @@ class AiBlogTask extends Command @@ -64,16 +68,15 @@ class AiBlogTask extends Command
64 } 68 }
65 69
66 /** 70 /**
67 - * @remark :请求方法  
68 - * @name :sendRequest  
69 - * @author :lyh  
70 - * @method :post  
71 - * @time :2025/3/19 16:48 71 + * 请求方法
  72 + * @param $task_id
  73 + * @return bool
  74 + * @throws \Exception
72 */ 75 */
73 public function sendRequest($task_id){ 76 public function sendRequest($task_id){
74 $aiBlogTaskModel = new AiBlogTaskModel(); 77 $aiBlogTaskModel = new AiBlogTaskModel();
75 $item = $aiBlogTaskModel->read(['id'=>$task_id]); 78 $item = $aiBlogTaskModel->read(['id'=>$task_id]);
76 - echo date('Y-m-d H:i:s') . '开始->任务id:' . $item['task_id'] . PHP_EOL; 79 + $this->output('start:project ID: ' . $item['project_id'] . ',task ID: ' . $task_id);
77 //获取配置 80 //获取配置
78 $aiSettingInfo = $this->getSetting($item['project_id']); 81 $aiSettingInfo = $this->getSetting($item['project_id']);
79 $aiBlogService = new AiBlogService(); 82 $aiBlogService = new AiBlogService();
@@ -82,7 +85,7 @@ class AiBlogTask extends Command @@ -82,7 +85,7 @@ class AiBlogTask extends Command
82 $aiBlogService->task_id = $item['task_id']; 85 $aiBlogService->task_id = $item['task_id'];
83 //拉取文章数据 86 //拉取文章数据
84 $result = $aiBlogService->getDetail(); 87 $result = $aiBlogService->getDetail();
85 - if(!isset($result['status']) || ($result['status'] != 200)){ 88 + if(empty($result['status']) || ($result['status'] != 200)){
86 if($item['sort'] < 5){ 89 if($item['sort'] < 5){
87 $aiBlogTaskModel->edit(['sort'=>$item['sort'] + 1],['id'=>$item['id']]); 90 $aiBlogTaskModel->edit(['sort'=>$item['sort'] + 1],['id'=>$item['id']]);
88 }else{ 91 }else{
@@ -90,36 +93,40 @@ class AiBlogTask extends Command @@ -90,36 +93,40 @@ class AiBlogTask extends Command
90 // 钉钉通知 93 // 钉钉通知
91 $dingService = new DingService(); 94 $dingService = new DingService();
92 $body = [ 95 $body = [
93 - 'keyword' => 'AI_BLOG生成错误',  
94 - 'msg' => '任务id:'.$item['task_id'].'拉取数据失败'.PHP_EOL.'返回信息:'.json_encode($result,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 96 + 'keyword' => 'AI_BLOG获取失败',
  97 + 'msg' => '任务ID:' . $item['task_id'] . PHP_EOL . '返回信息:' . json_encode($result,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
95 'isAtAll' => false, // 是否@所有人 98 'isAtAll' => false, // 是否@所有人
96 ]; 99 ];
97 $dingService->handle($body); 100 $dingService->handle($body);
98 } 101 }
99 - echo date('Y-m-d H:i:s'). '错误信息:'.json_encode($result,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES).PHP_EOL; 102 + $this->output('error: 数据获取失败,status:' . $result['status'] . ',message: ' . ($result['message'] ?? 'null'));
100 return false; 103 return false;
101 } 104 }
102 //保存当前项目ai_blog数据 105 //保存当前项目ai_blog数据
103 ProjectServer::useProject($item['project_id']); 106 ProjectServer::useProject($item['project_id']);
104 $aiBlogModel = new AiBlog(); 107 $aiBlogModel = new AiBlog();
105 - $aiBlogInfo = $aiBlogModel->read(['task_id'=>$item['task_id']],['id']); 108 + $aiBlogInfo = $aiBlogModel->read(['task_id'=>$item['task_id']],['id','route']);
106 if($aiBlogInfo === false){ 109 if($aiBlogInfo === false){
107 // 钉钉通知 110 // 钉钉通知
108 $dingService = new DingService(); 111 $dingService = new DingService();
109 $body = [ 112 $body = [
110 'keyword' => 'AI_BLOG生成错误', 113 'keyword' => 'AI_BLOG生成错误',
111 - 'msg' => '子任务不存在:'.$item['task_id'], 114 + 'msg' => '任务ID:' . $item['task_id'] . ', 子库获取数据失败, 检查子库数据是否被删除!',
112 'isAtAll' => false, // 是否@所有人 115 'isAtAll' => false, // 是否@所有人
113 ]; 116 ];
114 $dingService->handle($body); 117 $dingService->handle($body);
115 - echo '任务id不存在:'.$item['task_id'].PHP_EOL; 118 + $this->output('error: 子库获取数据失败, task id: ' . $task_id);
116 $aiBlogTaskModel->edit(['status'=>9],['id'=>$item['id']]); 119 $aiBlogTaskModel->edit(['status'=>9],['id'=>$item['id']]);
117 DB::disconnect('custom_mysql'); 120 DB::disconnect('custom_mysql');
118 return false; 121 return false;
119 } 122 }
  123 + //需要更新的路由
120 if (!in_array($result['data']['author_id'], $this->updateProject[$item['project_id']] ?? [])) { 124 if (!in_array($result['data']['author_id'], $this->updateProject[$item['project_id']] ?? [])) {
121 $this->updateProject[$item['project_id']][] = $result['data']['author_id']; 125 $this->updateProject[$item['project_id']][] = $result['data']['author_id'];
122 } 126 }
  127 + if (!in_array($aiBlogInfo['route'], $this->routes[$item['project_id']] ?? [])) {
  128 + $this->routes[$item['project_id']][] = $aiBlogInfo['route'];
  129 + }
123 //拿到返回的路由查看是否重复 130 //拿到返回的路由查看是否重复
124 $route = RouteMap::setRoute($result['data']['url'], RouteMap::SOURCE_AI_BLOG, $aiBlogInfo['id'], $item['project_id']); 131 $route = RouteMap::setRoute($result['data']['url'], RouteMap::SOURCE_AI_BLOG, $aiBlogInfo['id'], $item['project_id']);
125 if($route != $result['data']['url']){ 132 if($route != $result['data']['url']){
@@ -128,19 +135,16 @@ class AiBlogTask extends Command @@ -128,19 +135,16 @@ class AiBlogTask extends Command
128 $aiBlogModel->edit(['new_title'=>$result['data']['title'], 'image'=>$result['data']['thumb'], 'text'=>$result['data']['section'], 'author_id'=>$result['data']['author_id'],'seo_title'=>$result['data']['title'],'seo_keyword'=>$result['data']['keyword'],'seo_description'=>$result['data']['description'], 'route'=>$route ,'status'=>$aiBlogModel::STATUS_FINISH], ['task_id'=>$item['task_id']]); 135 $aiBlogModel->edit(['new_title'=>$result['data']['title'], 'image'=>$result['data']['thumb'], 'text'=>$result['data']['section'], 'author_id'=>$result['data']['author_id'],'seo_title'=>$result['data']['title'],'seo_keyword'=>$result['data']['keyword'],'seo_description'=>$result['data']['description'], 'route'=>$route ,'status'=>$aiBlogModel::STATUS_FINISH], ['task_id'=>$item['task_id']]);
129 DB::disconnect('custom_mysql'); 136 DB::disconnect('custom_mysql');
130 $aiBlogTaskModel->edit(['status'=>$aiBlogModel::STATUS_FINISH],['id'=>$item['id']]); 137 $aiBlogTaskModel->edit(['status'=>$aiBlogModel::STATUS_FINISH],['id'=>$item['id']]);
131 - echo date('Y-m-d H:i:s').'结束->任务id:' . $item['task_id'] . PHP_EOL; 138 + $this->output('success: task id: ' . $task_id);
132 return true; 139 return true;
133 } 140 }
134 141
135 /** 142 /**
136 - * @remark :获取任务id  
137 - * @name :getTaskId  
138 - * @author :lyh  
139 - * @method :post  
140 - * @time :2025/3/19 16:16  
141 - * @param : 143 + * 获取任务id
  144 + * @param int $finish_at
  145 + * @return mixed
142 */ 146 */
143 - public function getTaskId($finish_at = 1) 147 + public function getTaskId($finish_at = 2)
144 { 148 {
145 $task_id = Redis::rpop('ai_blog_task'); 149 $task_id = Redis::rpop('ai_blog_task');
146 if (empty($task_id)) { 150 if (empty($task_id)) {
@@ -148,9 +152,13 @@ class AiBlogTask extends Command @@ -148,9 +152,13 @@ class AiBlogTask extends Command
148 $this->updateProject($this->updateProject); 152 $this->updateProject($this->updateProject);
149 $this->updateProject = []; 153 $this->updateProject = [];
150 } 154 }
  155 + if(!empty($this->routes)){
  156 + $this->updateRoutes($this->routes);
  157 + $this->routes = [];
  158 + }
151 $aiBlogTaskModel = new AiBlogTaskModel(); 159 $aiBlogTaskModel = new AiBlogTaskModel();
152 $finish_at = date('Y-m-d H:i:s', strtotime('-' . $finish_at . ' hour')); 160 $finish_at = date('Y-m-d H:i:s', strtotime('-' . $finish_at . ' hour'));
153 - $ids = $aiBlogTaskModel->formatQuery(['status'=>$aiBlogTaskModel::STATUS_RUNNING,'type'=>$aiBlogTaskModel::TYPE_BLOG,'updated_at'=>['<=',$finish_at]])->pluck('id'); 161 + $ids = $aiBlogTaskModel->formatQuery(['status'=>$aiBlogTaskModel::STATUS_RUNNING, 'type'=>$aiBlogTaskModel::TYPE_BLOG, 'updated_at'=>['<=',$finish_at]])->pluck('id');
154 if(!empty($ids)){ 162 if(!empty($ids)){
155 foreach ($ids as $id) { 163 foreach ($ids as $id) {
156 Redis::lpush('ai_blog_task', $id); 164 Redis::lpush('ai_blog_task', $id);
@@ -162,11 +170,9 @@ class AiBlogTask extends Command @@ -162,11 +170,9 @@ class AiBlogTask extends Command
162 } 170 }
163 171
164 /** 172 /**
165 - * @remark :更新项目作者页面及列表页  
166 - * @name :updateProject  
167 - * @author :lyh  
168 - * @method :post  
169 - * @time :2025/3/4 10:25 173 + * 更新项目作者页面及列表页
  174 + * @param $updateProject
  175 + * @return bool
170 */ 176 */
171 public function updateProject($updateProject){ 177 public function updateProject($updateProject){
172 if(empty($updateProject)){ 178 if(empty($updateProject)){
@@ -175,38 +181,45 @@ class AiBlogTask extends Command @@ -175,38 +181,45 @@ class AiBlogTask extends Command
175 foreach ($updateProject as $project_id => $author){ 181 foreach ($updateProject as $project_id => $author){
176 ProjectServer::useProject($project_id); 182 ProjectServer::useProject($project_id);
177 $aiSettingInfo = $this->getSetting($project_id); 183 $aiSettingInfo = $this->getSetting($project_id);
  184 + $this->output('sync: list start, project_id: ' . $project_id);
178 $this->updateBlogList($aiSettingInfo); 185 $this->updateBlogList($aiSettingInfo);
  186 + $this->output('sync: list end');
179 //更新作者 187 //更新作者
  188 + $this->output('sync: author start, project_id: ' . $project_id);
180 foreach ($author as $val){ 189 foreach ($author as $val){
181 - $this->updateAiBlogAuthor($aiSettingInfo,$val); 190 + $this->updateAiBlogAuthor($aiSettingInfo,$val,$project_id);
182 } 191 }
  192 + $this->output('sync: author end');
183 DB::disconnect('custom_mysql'); 193 DB::disconnect('custom_mysql');
184 - $this->curlDelRoute($project_id);  
185 } 194 }
  195 +
186 return true; 196 return true;
187 } 197 }
188 198
189 /** 199 /**
190 - * @remark :获取项目配置  
191 - * @name :getSetting  
192 - * @author :lyh  
193 - * @method :post  
194 - * @time :2025/2/14 11:27 200 + * 获取项目配置
  201 + * @param $project_id
  202 + * @return bool
195 */ 203 */
196 - public function getSetting($project_id){ 204 + public function getSetting($project_id)
  205 + {
  206 + $project_setting = $this->projectSetting;
  207 + if (FALSE == empty($project_setting[$project_id])){
  208 + return $project_setting[$project_id];
  209 + }
197 $projectAiSettingModel = new ProjectAiSetting(); 210 $projectAiSettingModel = new ProjectAiSetting();
198 $aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$project_id]); 211 $aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$project_id]);
  212 + $this->projectSetting[$project_id] = $aiSettingInfo;
199 return $aiSettingInfo; 213 return $aiSettingInfo;
200 } 214 }
201 215
202 /** 216 /**
203 - * @remark :更新作者的页面  
204 - * @name :updateAiBlogAuthor  
205 - * @author :lyh  
206 - * @method :post  
207 - * @time :2025/2/21 11:53 217 + * 更新作者的页面
  218 + * @param $aiSettingInfo
  219 + * @param $author_id
  220 + * @return bool
208 */ 221 */
209 - public function updateAiBlogAuthor($aiSettingInfo,$author_id){ 222 + public function updateAiBlogAuthor($aiSettingInfo,$author_id,$project_id){
210 if(empty($author_id)){ 223 if(empty($author_id)){
211 return true; 224 return true;
212 } 225 }
@@ -218,7 +231,12 @@ class AiBlogTask extends Command @@ -218,7 +231,12 @@ class AiBlogTask extends Command
218 if(isset($result['status']) && $result['status'] == 200){ 231 if(isset($result['status']) && $result['status'] == 200){
219 //当前作者的页面 232 //当前作者的页面
220 $aiBlogAuthorModel = new AiBlogAuthor(); 233 $aiBlogAuthorModel = new AiBlogAuthor();
221 - if(!empty($result['data']['section'])){ 234 + $authorInfo = $aiBlogAuthorModel->read(['author_id'=>$author_id],['id','route']);
  235 + if($authorInfo !== false && !empty($result['data']['section'])){
  236 + //需要更新的路由
  237 + if (!in_array($authorInfo['route'], $this->routes[$project_id] ?? [])) {
  238 + $this->routes[$project_id][] = $authorInfo['route'];
  239 + }
222 $aiBlogAuthorModel->edit(['text'=>$result['data']['section']],['author_id'=>$author_id]); 240 $aiBlogAuthorModel->edit(['text'=>$result['data']['section']],['author_id'=>$author_id]);
223 } 241 }
224 } 242 }
@@ -226,11 +244,9 @@ class AiBlogTask extends Command @@ -226,11 +244,9 @@ class AiBlogTask extends Command
226 } 244 }
227 245
228 /** 246 /**
229 - * @remark :更新列表页  
230 - * @name :updateBlogList  
231 - * @author :lyh  
232 - * @method :post  
233 - * @time :2025/2/26 15:42 247 + * 更新列表页
  248 + * @param $aiSettingInfo
  249 + * @return bool
234 */ 250 */
235 public function updateBlogList($aiSettingInfo){ 251 public function updateBlogList($aiSettingInfo){
236 $aiBlogService = new AiBlogService(); 252 $aiBlogService = new AiBlogService();
@@ -268,22 +284,24 @@ class AiBlogTask extends Command @@ -268,22 +284,24 @@ class AiBlogTask extends Command
268 } 284 }
269 285
270 /** 286 /**
271 - * @remark :通知C端生成界面  
272 - * @name :sendNotice  
273 - * @author :lyh  
274 - * @method :post  
275 - * @time :2025/3/6 11:51 287 + * 通知C端生成界面
  288 + * @param $project_id
  289 + * @return bool
276 */ 290 */
277 - public function curlDelRoute($project_id){ 291 + public function updateRoutes($routes){
278 $domainModel = new DomainInfo(); 292 $domainModel = new DomainInfo();
279 - //获取项目域名  
280 - $domain = $domainModel->getProjectIdDomain($project_id);  
281 - if(!empty($domain)){ 293 + $project_model = new Project();
  294 + foreach ($routes as $project_id => $route){
  295 + $route[] = 'top-blog';
  296 + $domain = $domainModel->getProjectIdDomain($project_id);
  297 + if (empty($domain)) {
  298 + $this->output('send: 域名不存在, project id: ' . $project_id);
  299 + return true;
  300 + }
282 //判断是否是自建站服务器,如果是,不请求C端接口,数据直接入库 301 //判断是否是自建站服务器,如果是,不请求C端接口,数据直接入库
283 - $project_model = new Project();  
284 $project_info = $project_model->read(['id'=>$project_id],['serve_id']); 302 $project_info = $project_model->read(['id'=>$project_id],['serve_id']);
285 if(!$project_info){ 303 if(!$project_info){
286 - echo '项目不存在:' . $project_id . PHP_EOL . date('Y-m-d H:i:s'); 304 + $this->output('send: 项目不存在, project id: ' . $project_id);
287 return true; 305 return true;
288 } 306 }
289 $serve_ip_model = new ServersIp(); 307 $serve_ip_model = new ServersIp();
@@ -300,23 +318,41 @@ class AiBlogTask extends Command @@ -300,23 +318,41 @@ class AiBlogTask extends Command
300 'status' => ['!=',Notify::STATUS_FINISH_SITEMAP] 318 'status' => ['!=',Notify::STATUS_FINISH_SITEMAP]
301 ]; 319 ];
302 $notify = $notify_model->read($data,['id']); 320 $notify = $notify_model->read($data,['id']);
303 -  
304 if(!$notify){ 321 if(!$notify){
305 $domain_array = parse_url($domain); 322 $domain_array = parse_url($domain);
306 - $data['data'] = Arr::a2s(['domain'=>$domain_array['host'],'url'=>[],'language'=>[]]); 323 + $data['data'] = Arr::a2s(['domain'=>$domain_array['host'],'url'=>$route,'language'=>[]]);
307 $data['status'] = Notify::STATUS_INIT; 324 $data['status'] = Notify::STATUS_INIT;
308 $data['sort'] = 2; 325 $data['sort'] = 2;
309 $notify_model->add($data); 326 $notify_model->add($data);
310 } 327 }
311 - echo '自建站项目:'.$project_id.'更新'; 328 + $this->output('send: 自建站项目, project id: ' . $project_id);
312 }else{ 329 }else{
313 - $url = $domain.'api/update_page/?project_id='.$project_id.'&route=7';  
314 - $res = http_get($url);  
315 - echo '通知C端:'.json_encode($res,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES).PHP_EOL; 330 + $c_url = $domain.'api/update_page/';
  331 + $param = [
  332 + 'project_id' => $project_id,
  333 + 'type' => 1,
  334 + 'route' => 3,
  335 + 'url' => $route,
  336 + 'language'=> [],
  337 + 'is_sitemap' => 0
  338 + ];
  339 + $res = http_post($c_url, json_encode($param,true));
  340 + $this->output('notify: project id: ' . $project_id . ', result: ' . json_encode($res,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
316 } 341 }
317 - }else{  
318 - echo '域名不存在:' . $project_id . PHP_EOL . date('Y-m-d H:i:s');  
319 } 342 }
320 return true; 343 return true;
321 } 344 }
  345 +
  346 + /**
  347 + * 输入日志
  348 + * @param $message
  349 + * @return bool
  350 + */
  351 + public function output($message)
  352 + {
  353 + $message = date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL;
  354 + echo $message;
  355 + file_put_contents(storage_path('logs/AiBlog/') . date('Ymd') . '.log', $message, FILE_APPEND);
  356 + return true;
  357 + }
322 } 358 }
@@ -11,6 +11,7 @@ namespace App\Console\Commands\DayCount; @@ -11,6 +11,7 @@ namespace App\Console\Commands\DayCount;
11 11
12 use App\Models\Manage\ManageHr; 12 use App\Models\Manage\ManageHr;
13 use App\Models\Project\Project; 13 use App\Models\Project\Project;
  14 +use App\Models\RankData\RankDataLog;
14 use Carbon\Carbon; 15 use Carbon\Carbon;
15 use App\Models\HomeCount\AfterCount as AfterCountModel; 16 use App\Models\HomeCount\AfterCount as AfterCountModel;
16 use Illuminate\Console\Command; 17 use Illuminate\Console\Command;
@@ -58,26 +59,59 @@ class AfterCount extends Command @@ -58,26 +59,59 @@ class AfterCount extends Command
58 public function _action(){ 59 public function _action(){
59 $this->managerHrModel = new ManageHr(); 60 $this->managerHrModel = new ManageHr();
60 $projectModel = new Project(); 61 $projectModel = new Project();
  62 + $rankDataLogModel = new RankDataLog();
61 $todayMidnight = date('Y-m-d 00:00:00', strtotime('today')); 63 $todayMidnight = date('Y-m-d 00:00:00', strtotime('today'));
62 $saveData = []; 64 $saveData = [];
  65 + $projectIdArr = $rankDataLogModel->selectField(['is_compliance'=>1,'lang'=>null,'date'=>date('Y-m-d', strtotime('-3 months'))],'project_id');//3个月前达标的项目id
63 foreach ($this->after_manager as $key => $valM){ 66 foreach ($this->after_manager as $key => $valM){
64 $idArr = $this->managerHrModel->selectField(['name'=>['in',$valM]],'id'); 67 $idArr = $this->managerHrModel->selectField(['name'=>['in',$valM]],'id');
65 - $project_count = $projectModel->where('gl_project.extend_type',0)->where('gl_project.delete_status',0)->where('gl_project.created_at','<=',$todayMidnight)->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)->whereIn('gl_project.type',[2,4])->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')->count();  
66 - $qualified_count = $projectModel->where('gl_project.extend_type',0)->where('gl_project.delete_status',0)->where('gl_project.created_at','<=',$todayMidnight)->where('gl_project.is_remain_today',1)->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)->whereIn('gl_project.type',[2,4])->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')->count(); 68 + $project_count = $projectModel->where('gl_project.extend_type',0)
  69 + ->where('gl_project.delete_status',0)
  70 + ->where('gl_project.created_at','<=',$todayMidnight)
  71 + ->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
  72 + ->whereIn('gl_project.type',[2,4])
  73 + ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')->count();
  74 + $qualified_count = $projectModel->where('gl_project.extend_type',0)
  75 + ->where('gl_project.delete_status',0)
  76 + ->where('gl_project.created_at','<=',$todayMidnight)
  77 + ->where('gl_project.is_remain_today',1)
  78 + ->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
  79 + ->whereIn('gl_project.type',[2,4])
  80 + ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')->count();
67 $rate = number_format($qualified_count / $project_count, 2); 81 $rate = number_format($qualified_count / $project_count, 2);
68 $threeMonthsAgo = date('Y-m-d 00:00:00', strtotime('-3 months')); 82 $threeMonthsAgo = date('Y-m-d 00:00:00', strtotime('-3 months'));
69 - $three_project_count = $projectModel->where('gl_project.extend_type',0)->where('gl_project.delete_status',0)->where('gl_project.created_at','<=',$threeMonthsAgo)->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)->whereIn('gl_project.type',[2,4])->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')->count();  
70 - $three_qualified_count = $projectModel->where('gl_project.extend_type',0)->where('gl_project.delete_status',0)->where('gl_project.created_at','<=',$threeMonthsAgo)->where('gl_project.is_remain_today',1)->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)->whereIn('gl_project.type',[2,4])->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')->count(); 83 + $three_project_count = $projectModel->where('gl_project.extend_type',0)
  84 + ->where('gl_project.delete_status',0)
  85 + ->where('gl_project.created_at','<=',$threeMonthsAgo)
  86 + ->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
  87 + ->whereIn('gl_project.type',[2,4])
  88 + ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')->count();
  89 + $three_qualified_count = $projectModel->where('gl_project.extend_type',0)
  90 + ->whereIn('gl_project.id',$projectIdArr)
  91 + ->where('gl_project.delete_status',0)
  92 + ->where('gl_project.created_at','<=',$threeMonthsAgo)
  93 + ->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
  94 + ->whereIn('gl_project.type',[2,4])
  95 + ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')->count();
71 $three_rate = number_format($three_qualified_count / $three_project_count, 2); 96 $three_rate = number_format($three_qualified_count / $three_project_count, 2);
  97 + $data = $projectModel->where('gl_project.extend_type',0)
  98 + ->where('gl_project.delete_status',0)
  99 + ->where('gl_project.created_at','<=',$todayMidnight)
  100 + ->where('gl_project.is_remain_today',1)
  101 + ->whereIn('gl_project_deploy_optimize.optimist_mid',$idArr)
  102 + ->whereIn('gl_project.type',[2,4])
  103 + ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')
  104 + ->pluck('gl_project.title')->toArray();
72 $saveData[] = [ 105 $saveData[] = [
73 'date'=>date('Y-m-d', strtotime('yesterday')), 106 'date'=>date('Y-m-d', strtotime('yesterday')),
74 'type'=> $key, 107 'type'=> $key,
75 'project_count'=>$project_count, 108 'project_count'=>$project_count,
76 'qualified_count'=>$qualified_count, 109 'qualified_count'=>$qualified_count,
77 'rate'=>$rate, 110 'rate'=>$rate,
78 - 'three_project_count'=>$three_project_count,  
79 - 'three_qualified_count'=>$three_qualified_count,  
80 - 'three_rate'=>$three_rate, 111 + 'three_project_count'=>$project_count - $three_project_count,
  112 + 'three_qualified_count'=>$qualified_count - $three_qualified_count,
  113 + 'three_rate'=>$rate - $three_rate,
  114 + 'data' => json_encode($data,true)
81 ]; 115 ];
82 } 116 }
83 return $saveData; 117 return $saveData;
@@ -125,7 +125,9 @@ class RemainDay extends Command @@ -125,7 +125,9 @@ class RemainDay extends Command
125 continue; 125 continue;
126 } 126 }
127 $diff = time() - strtotime($opInfo['start_date'] ?? $item['uptime']); 127 $diff = time() - strtotime($opInfo['start_date'] ?? $item['uptime']);
128 - $remain_day = $deploy_build['service_duration'] - floor($diff / (60 * 60 * 24)); 128 + $compliance_day = floor($diff / (60 * 60 * 24));
  129 + $remain_day = $deploy_build['service_duration'] - $compliance_day;
  130 +
129 }else{ 131 }else{
130 $compliance_day = ($item['finish_remain_day'] ?? 0); 132 $compliance_day = ($item['finish_remain_day'] ?? 0);
131 $remain_day = $deploy_build['service_duration'] - $compliance_day; 133 $remain_day = $deploy_build['service_duration'] - $compliance_day;
@@ -134,7 +136,8 @@ class RemainDay extends Command @@ -134,7 +136,8 @@ class RemainDay extends Command
134 //普通建站项目 136 //普通建站项目
135 if($item['uptime']){ 137 if($item['uptime']){
136 $diff = time() - strtotime($item['uptime']); 138 $diff = time() - strtotime($item['uptime']);
137 - $remain_day = $deploy_build['service_duration'] - floor($diff / (60 * 60 * 24)); 139 + $compliance_day = floor($diff / (60 * 60 * 24));
  140 + $remain_day = $deploy_build['service_duration'] - $compliance_day;
138 }else{ 141 }else{
139 $remain_day = $deploy_build['service_duration']; 142 $remain_day = $deploy_build['service_duration'];
140 } 143 }
@@ -144,7 +147,7 @@ class RemainDay extends Command @@ -144,7 +147,7 @@ class RemainDay extends Command
144 $remain_day = 0; 147 $remain_day = 0;
145 $extend_type = Project::TYPE_FIVE; 148 $extend_type = Project::TYPE_FIVE;
146 } 149 }
147 - $this->project->edit(['remain_day'=>$remain_day,'extend_type'=>$extend_type],['id'=>$item['id']]); 150 + $this->project->edit(['remain_day'=>$remain_day,'extend_type'=>$extend_type,'finish_remain_day'=>$compliance_day ?? 0],['id'=>$item['id']]);
148 echo 'end->项目id:' . $item['id'] . '执行时间:'. date('Y-m-d H:i:s') . PHP_EOL; 151 echo 'end->项目id:' . $item['id'] . '执行时间:'. date('Y-m-d H:i:s') . PHP_EOL;
149 } 152 }
150 return true; 153 return true;
@@ -16,6 +16,8 @@ use App\Models\Product\CategoryRelated; @@ -16,6 +16,8 @@ use App\Models\Product\CategoryRelated;
16 use App\Models\Product\Product; 16 use App\Models\Product\Product;
17 use App\Models\ProjectAssociation\ProjectAssociation; 17 use App\Models\ProjectAssociation\ProjectAssociation;
18 use App\Models\RouteMap\RouteMap; 18 use App\Models\RouteMap\RouteMap;
  19 +use App\Models\Visit\Visit;
  20 +use App\Models\Visit\VisitItem;
19 use App\Models\Workchat\MessagePush; 21 use App\Models\Workchat\MessagePush;
20 use App\Services\ProjectServer; 22 use App\Services\ProjectServer;
21 use Illuminate\Console\Command; 23 use Illuminate\Console\Command;
@@ -40,96 +42,115 @@ class DownloadProject extends Command @@ -40,96 +42,115 @@ class DownloadProject extends Command
40 protected $description = '导出项目数据'; 42 protected $description = '导出项目数据';
41 43
42 public function handle(){ 44 public function handle(){
43 - $v6WeekModel = new V6WeeklyReport();  
44 - $lists = $v6WeekModel->list([],'id',['*'],'desc',100);  
45 echo date('Y-m-d H:i:s') . 'start' . PHP_EOL; 45 echo date('Y-m-d H:i:s') . 'start' . PHP_EOL;
46 - foreach ($lists as $data){  
47 - $this->workChatMessage($data,$data['project_id']);  
48 - } 46 + ProjectServer::useProject(535);
  47 + $this->model = new Visit();
  48 + $data = $this->importVisit();
  49 + dd($data);
  50 + DB::disconnect('custom_mysql');
49 echo date('Y-m-d H:i:s') . 'end' . PHP_EOL; 51 echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
50 return true; 52 return true;
51 } 53 }
52 54
53 - public function downloadProduct() 55 + /**
  56 + * @remark :导出明细
  57 + * @name :importVisit
  58 + * @author :lyh
  59 + * @method :post
  60 + * @time :2025/4/8 11:34
  61 + */
  62 + public function importVisit()
54 { 63 {
55 - $product = new Product();  
56 -// $filed = ['id', 'project_id', 'title' ,'thumb' , 'route' ,'intro','content',  
57 -// 'category_id', 'status','seo_mate'];  
58 - $filed = ['id','title'];  
59 - $this->order = 'sort';  
60 - $lists = $product->list(['status'=>1],'id',$filed);  
61 - if(!empty($lists)){  
62 -// $cate_data = $this->getCategoryList();//分类  
63 - foreach ($lists as $k => $v){  
64 - echo date('Y-m-d H:i:s') . '产品id:'.$v['id'] . PHP_EOL;  
65 -// $v['url'] = 'https://www.autsikinta.com/' . getRouteMap(RouteMap::SOURCE_PRODUCT,$v['id']);  
66 -// $v['category_id_text'] = $this->categoryName($v['id'],$cate_data);  
67 -// //ToDo::处理图片及文件  
68 -// if(!empty($v['thumb']) && !empty($v['thumb']['url'])){  
69 -// $v['images'] = getImageUrl($v['thumb']['url']);  
70 -// }else{  
71 -// $v['images'] = '';  
72 -// }  
73 - $lists[$k] = $v; 64 + $lists = $this->model->list();
  65 + if(!empty($lists) && !empty($lists['list'])){
  66 + foreach ($lists as $v){
  67 + $customer_visit_id[] = $v['id'];
74 } 68 }
75 - }  
76 - return $lists;  
77 - }  
78 - public function categoryName($product_id,$data){  
79 - $cateRelatedModel = new CategoryRelated();  
80 - $category_id = $cateRelatedModel->where('product_id',$product_id)->pluck('cate_id')->toArray();  
81 - $category_name = '';  
82 - if(!empty($category_id) && !empty($data)){  
83 - foreach ($category_id as $v){  
84 - if(isset($data[$v])){  
85 - $category_name .= $data[$v].','; 69 + $itemModel = new VisitItem();
  70 + $itemList = $itemModel->list(['customer_visit_id'=>['in',$customer_visit_id]],['customer_visit_id','url']);
  71 + foreach ($lists as $key => $value){
  72 + $sub = [];
  73 + foreach ($itemList as $sonValue){
  74 + if($value['id'] == $sonValue['customer_visit_id']){
  75 + $sub[] = $sonValue;
  76 + }
86 } 77 }
  78 + $value['sub'] = $sub;
  79 + $lists[$key] = $value;
87 } 80 }
88 - $category_name = trim($category_name,',');  
89 } 81 }
90 - return $category_name; 82 + return $lists;
91 } 83 }
  84 +
92 /** 85 /**
93 - * @remark :获取所有分类  
94 - * @name :getCategoryList 86 + * @remark :导出访问明细
  87 + * @name :exportData
95 * @author :lyh 88 * @author :lyh
96 * @method :post 89 * @method :post
97 - * @time :2023/9/14 13:56 90 + * @time :2025/4/8 11:32
98 */ 91 */
99 - public function getCategoryList(){  
100 - $data = Common::get_user_cache('product_category',1225);  
101 - if(empty($data)){  
102 - $categoryModel = new Category();  
103 - $data = [];  
104 - $cateList = $categoryModel->list(['project_id'=>1225],['id','title']);  
105 - if(!empty($cateList)){  
106 - foreach ($cateList as $value){  
107 - $data[$value['id']] = $value['title'];  
108 - }  
109 - }  
110 - Common::set_user_cache($data,'product_category',1225); 92 + public function exportData($data){
  93 + // 创建一个新的 Excel 电子表格实例
  94 + $spreadsheet = new Spreadsheet();
  95 + $sheet = $spreadsheet->getActiveSheet();
  96 + // 添加表头
  97 + $sheet->setCellValue('A1', '浏览时间');
  98 + $sheet->setCellValue('B1', '访客来源');
  99 + $sheet->setCellValue('C1', '访客入路页面');
  100 + $sheet->setCellValue('D1', '终端');
  101 + $sheet->setCellValue('E1', '国家ip');
  102 + $sheet->setCellValue('F1', '深度访问页数');
  103 + $sheet->setCellValue('G1', '国家');
  104 + $rowCount = 2;
  105 + foreach ($data as $v) {
  106 + $sheet->setCellValue('A' . $rowCount, $v['created_at']);
  107 + $sheet->setCellValue('B' . $rowCount, $v['referrer_url']);
  108 + $sheet->setCellValue('C' . $rowCount, $v['url']);
  109 + $sheet->setCellValue('D' . $rowCount, $v['device_text']);
  110 + $sheet->setCellValue('E' . $rowCount, $v['ip']);
  111 + $sheet->setCellValue('F' . $rowCount, $v['depth']);
  112 + $sheet->setCellValue('G' . $rowCount, $v['country']);
  113 + $rowCount++;
111 } 114 }
112 - return $data; 115 + // 创建一个新的 Excel Writer 对象
  116 + $writer = new Xlsx($spreadsheet);
  117 + $filename = time().'.xlsx';
  118 + // 设置导出文件的保存路径和文件名
  119 + $filePath = public_path('upload/excel/'.$filename);
  120 + // 导出 Excel 文件
  121 + $writer->save($filePath);
  122 + echo date('Y-m-d H:i:s') . 'file_link:'.url('upload/excel/'.$filename) . PHP_EOL;
  123 + // 返回导出文件的响应
  124 + return ['file_link'=>url('upload/excel/'.$filename)];
113 } 125 }
  126 +
114 // public function exportData($data){ 127 // public function exportData($data){
115 // // 创建一个新的 Excel 电子表格实例 128 // // 创建一个新的 Excel 电子表格实例
116 // $spreadsheet = new Spreadsheet(); 129 // $spreadsheet = new Spreadsheet();
117 // $sheet = $spreadsheet->getActiveSheet(); 130 // $sheet = $spreadsheet->getActiveSheet();
118 // // 添加表头 131 // // 添加表头
119 -// $sheet->setCellValue('A1', '浏览时间');  
120 -// $sheet->setCellValue('B1', '访客来源');  
121 -// $sheet->setCellValue('C1', '访客入路页面');  
122 -// $sheet->setCellValue('D1', '终端');  
123 -// $sheet->setCellValue('E1', '国家ip');  
124 -// $sheet->setCellValue('F1', '深度访问页数'); 132 +// $sheet->setCellValue('A1', '产品名称');
  133 +//// $sheet->setCellValue('B1', '产品短描述');
  134 +//// $sheet->setCellValue('C1', '产品内容');
  135 +//// $sheet->setCellValue('D1', '产品路由');
  136 +//// $sheet->setCellValue('E1', '产品分类');
  137 +//// $sheet->setCellValue('F1', '产品状态');
  138 +//// $sheet->setCellValue('G1', '产品主图');
  139 +//// $sheet->setCellValue('H1', '产品seo_title');
  140 +//// $sheet->setCellValue('I1', '产品seo_keyword');
  141 +//// $sheet->setCellValue('J1', '产品seo_title');
125 // $rowCount = 2; 142 // $rowCount = 2;
126 // foreach ($data as $v) { 143 // foreach ($data as $v) {
127 -// $sheet->setCellValue('A' . $rowCount, $v['created_at']);  
128 -// $sheet->setCellValue('B' . $rowCount, $v['referrer_url']);  
129 -// $sheet->setCellValue('C' . $rowCount, $v['url']);  
130 -// $sheet->setCellValue('D' . $rowCount, $v['device_text']);  
131 -// $sheet->setCellValue('E' . $rowCount, $v['ip']);  
132 -// $sheet->setCellValue('F' . $rowCount, $v['depth']); 144 +// $sheet->setCellValue('A' . $rowCount, $v['title']);
  145 +//// $sheet->setCellValue('B' . $rowCount, $v['intro']);
  146 +//// $sheet->setCellValue('C' . $rowCount, $v['content']);
  147 +//// $sheet->setCellValue('D' . $rowCount, $v['url']);
  148 +//// $sheet->setCellValue('E' . $rowCount, $v['category_id_text']);
  149 +//// $sheet->setCellValue('F' . $rowCount, '发布中');
  150 +//// $sheet->setCellValue('G' . $rowCount, $v['images']);
  151 +//// $sheet->setCellValue('H' . $rowCount, $v['seo_mate']['title']);
  152 +//// $sheet->setCellValue('I' . $rowCount, $v['seo_mate']['keyword']);
  153 +//// $sheet->setCellValue('J' . $rowCount, $v['seo_mate']['description']);
133 // $rowCount++; 154 // $rowCount++;
134 // } 155 // }
135 // // 创建一个新的 Excel Writer 对象 156 // // 创建一个新的 Excel Writer 对象
@@ -143,69 +164,28 @@ class DownloadProject extends Command @@ -143,69 +164,28 @@ class DownloadProject extends Command
143 // // 返回导出文件的响应 164 // // 返回导出文件的响应
144 // return ['file_link'=>url('upload/excel/'.$filename)]; 165 // return ['file_link'=>url('upload/excel/'.$filename)];
145 // } 166 // }
146 -  
147 - public function exportData($data){  
148 - // 创建一个新的 Excel 电子表格实例  
149 - $spreadsheet = new Spreadsheet();  
150 - $sheet = $spreadsheet->getActiveSheet();  
151 - // 添加表头  
152 - $sheet->setCellValue('A1', '产品名称');  
153 -// $sheet->setCellValue('B1', '产品短描述');  
154 -// $sheet->setCellValue('C1', '产品内容');  
155 -// $sheet->setCellValue('D1', '产品路由');  
156 -// $sheet->setCellValue('E1', '产品分类');  
157 -// $sheet->setCellValue('F1', '产品状态');  
158 -// $sheet->setCellValue('G1', '产品主图');  
159 -// $sheet->setCellValue('H1', '产品seo_title');  
160 -// $sheet->setCellValue('I1', '产品seo_keyword');  
161 -// $sheet->setCellValue('J1', '产品seo_title');  
162 - $rowCount = 2;  
163 - foreach ($data as $v) {  
164 - $sheet->setCellValue('A' . $rowCount, $v['title']);  
165 -// $sheet->setCellValue('B' . $rowCount, $v['intro']);  
166 -// $sheet->setCellValue('C' . $rowCount, $v['content']);  
167 -// $sheet->setCellValue('D' . $rowCount, $v['url']);  
168 -// $sheet->setCellValue('E' . $rowCount, $v['category_id_text']);  
169 -// $sheet->setCellValue('F' . $rowCount, '发布中');  
170 -// $sheet->setCellValue('G' . $rowCount, $v['images']);  
171 -// $sheet->setCellValue('H' . $rowCount, $v['seo_mate']['title']);  
172 -// $sheet->setCellValue('I' . $rowCount, $v['seo_mate']['keyword']);  
173 -// $sheet->setCellValue('J' . $rowCount, $v['seo_mate']['description']);  
174 - $rowCount++;  
175 - }  
176 - // 创建一个新的 Excel Writer 对象  
177 - $writer = new Xlsx($spreadsheet);  
178 - $filename = time().'.xlsx';  
179 - // 设置导出文件的保存路径和文件名  
180 - $filePath = public_path('upload/excel/'.$filename);  
181 - // 导出 Excel 文件  
182 - $writer->save($filePath);  
183 - echo date('Y-m-d H:i:s') . 'file_link:'.url('upload/excel/'.$filename) . PHP_EOL;  
184 - // 返回导出文件的响应  
185 - return ['file_link'=>url('upload/excel/'.$filename)];  
186 - }  
187 -  
188 - public function downloadItem($filed = ['id','depth','created_at','referrer_url','url','device_port','country','ip']){  
189 - $visitModel = new Visit();  
190 - $page = 1;  
191 - $pageSize = 3000;  
192 - $lists = $visitModel->lists(['updated_date'=>['between',['2025-02-01','2025-02-31']]],$page,$pageSize,'id',$filed);  
193 - foreach ($lists as $v){  
194 - $customer_visit_id[] = $v['id'];  
195 - }  
196 - $itemModel = new VisitItem();  
197 - $itemList = $itemModel->list(['customer_visit_id'=>['in',$customer_visit_id]],['customer_visit_id','url']);  
198 - foreach ($lists as $key => $value){  
199 - $sub = [];  
200 - foreach ($itemList as $sonValue){  
201 - if($value['id'] == $sonValue['customer_visit_id']){  
202 - $sub[] = $sonValue;  
203 - }  
204 - }  
205 - $value['sub'] = $sub;  
206 - $lists[$key] = $value;  
207 - }  
208 - return $lists;  
209 - } 167 +//
  168 +// public function downloadItem($filed = ['id','depth','created_at','referrer_url','url','device_port','country','ip']){
  169 +// $visitModel = new Visit();
  170 +// $page = 1;
  171 +// $pageSize = 3000;
  172 +// $lists = $visitModel->lists(['updated_date'=>['between',['2025-02-01','2025-02-31']]],$page,$pageSize,'id',$filed);
  173 +// foreach ($lists as $v){
  174 +// $customer_visit_id[] = $v['id'];
  175 +// }
  176 +// $itemModel = new VisitItem();
  177 +// $itemList = $itemModel->list(['customer_visit_id'=>['in',$customer_visit_id]],['customer_visit_id','url']);
  178 +// foreach ($lists as $key => $value){
  179 +// $sub = [];
  180 +// foreach ($itemList as $sonValue){
  181 +// if($value['id'] == $sonValue['customer_visit_id']){
  182 +// $sub[] = $sonValue;
  183 +// }
  184 +// }
  185 +// $value['sub'] = $sub;
  186 +// $lists[$key] = $value;
  187 +// }
  188 +// return $lists;
  189 +// }
210 190
211 } 191 }
@@ -52,9 +52,9 @@ class LyhImportTest extends Command @@ -52,9 +52,9 @@ class LyhImportTest extends Command
52 * @time :2023/11/20 15:13 52 * @time :2023/11/20 15:13
53 */ 53 */
54 public function handle(){ 54 public function handle(){
55 - ProjectServer::useProject(2878); 55 + ProjectServer::useProject(3283);
56 echo date('Y-m-d H:i:s') . 'start' . PHP_EOL; 56 echo date('Y-m-d H:i:s') . 'start' . PHP_EOL;
57 - $this->importProductCategory('https://ecdn6.globalso.com/upload/p/2878/file/2025-03/products.csv',2878); 57 + $this->importProductCategory('https://ecdn6.globalso.com/upload/p/3283/file/2025-04/zhouyongpaxu.csv',3283);
58 DB::disconnect('custom_mysql'); 58 DB::disconnect('custom_mysql');
59 echo date('Y-m-d H:i:s') . 'end' . PHP_EOL; 59 echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
60 } 60 }
@@ -93,18 +93,19 @@ class LyhImportTest extends Command @@ -93,18 +93,19 @@ class LyhImportTest extends Command
93 continue; 93 continue;
94 } 94 }
95 try { 95 try {
96 - $id = $categoryModel->addReturnId(['project_id'=>$project_id,'title'=>$val[1],'seo_title'=>$val[0],'seo_des'=>$val[2]]);  
97 - $pid = 0;  
98 - if($val[2] != 0){  
99 - //查询上级id  
100 - $pidCate = $categoryModel->read(['seo_title'=>$val[2]]);  
101 - if($pidCate !== false){  
102 - $pid = $pidCate['id'];  
103 - }  
104 - }  
105 - $route = RouteMap::setRoute($val[1],RouteMap::SOURCE_PRODUCT_CATE,$id,$project_id);  
106 - $categoryModel->edit(['route'=>$route,'pid'=>$pid],['id'=>$id]);  
107 - echo date('Y-m-d H:i:s') . '产品分类id:'. $id.PHP_EOL; 96 + $categoryModel->edit(['sort'=>$val[1]],['title'=>$val[0]]);
  97 +// $id = $categoryModel->addReturnId(['project_id'=>$project_id,'title'=>$val[1],'seo_title'=>$val[0],'seo_des'=>$val[2]]);
  98 +// $pid = 0;
  99 +// if($val[2] != 0){
  100 +// //查询上级id
  101 +// $pidCate = $categoryModel->read(['seo_title'=>$val[2]]);
  102 +// if($pidCate !== false){
  103 +// $pid = $pidCate['id'];
  104 +// }
  105 +// }
  106 +// $route = RouteMap::setRoute($val[1],RouteMap::SOURCE_PRODUCT_CATE,$id,$project_id);
  107 +// $categoryModel->edit(['route'=>$route,'pid'=>$pid],['id'=>$id]);
  108 + echo date('Y-m-d H:i:s') . '产品分类id:'.PHP_EOL;
108 }catch (\Exception $e){ 109 }catch (\Exception $e){
109 echo date('Y-m-d H:i:s') . '跳过的名称:'. $val[1]; 110 echo date('Y-m-d H:i:s') . '跳过的名称:'. $val[1];
110 continue; 111 continue;
@@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
7 */ 7 */
8 namespace App\Console\Commands\Product; 8 namespace App\Console\Commands\Product;
9 9
  10 +use App\Helper\Common;
  11 +use App\Models\Com\NoticeLog;
10 use App\Models\Product\Keyword; 12 use App\Models\Product\Keyword;
11 use App\Models\Project\AggregateKeyword; 13 use App\Models\Project\AggregateKeyword;
12 use App\Services\ProjectServer; 14 use App\Services\ProjectServer;
@@ -56,6 +58,8 @@ class OptimizeSetKeywordSync extends Command @@ -56,6 +58,8 @@ class OptimizeSetKeywordSync extends Command
56 $item->status = AggregateKeyword::STATUS_FINISH; 58 $item->status = AggregateKeyword::STATUS_FINISH;
57 $item->save(); 59 $item->save();
58 } 60 }
  61 + Common::del_user_cache('product_keyword',$this->user['project_id']);
  62 + NoticeLog::createLog(NoticeLog::TYPE_INIT_KEYWORD, ['project_id' => $this->user['project_id']]);
59 return true; 63 return true;
60 } 64 }
61 65
@@ -281,13 +281,12 @@ class WeekProject extends Command @@ -281,13 +281,12 @@ class WeekProject extends Command
281 foreach ($arr as $key => $val){ 281 foreach ($arr as $key => $val){
282 $content .= ($key+1).','.$val.PHP_EOL.PHP_EOL; 282 $content .= ($key+1).','.$val.PHP_EOL.PHP_EOL;
283 } 283 }
284 - $timestamp = strtotime('tomorrow 9:00 AM');  
285 - $tomorrowNineAM = date('Y-m-d H:i:s', $timestamp); 284 + $tomorrowNineAM = date('Y-m-d 09:00:00', time());
286 if(empty($content)){ 285 if(empty($content)){
287 return true; 286 return true;
288 } 287 }
289 $tips = 'Tips:'.PHP_EOL.'1、全球搜V6.0系统提供网页TDK、H标签、Img标签等用户自定义编辑接口且辅以AI创作工具,用户可进一步对相关优化设置进行精细化优化与调整;'.PHP_EOL.'2、全球搜V6.0系统提供小语种页面精准校对翻译功能,用户可进一步对已翻译小语种页面进行人工翻译校对;'.PHP_EOL.'3、全球搜V6.0系统支持绑定Facebook、LinkedIn、X(原Twitter)等社媒账号,可一键同步转发网站上发布的产品和新闻至社媒账号动态,建议用户用起来哦;'.PHP_EOL.'4、如用户有较丰富的企业、产品、服务相关视频素材,全球搜建议用户及时创建YouTube主页,并在YouTube和网站相关网页上同步发布视频;'; 288 $tips = 'Tips:'.PHP_EOL.'1、全球搜V6.0系统提供网页TDK、H标签、Img标签等用户自定义编辑接口且辅以AI创作工具,用户可进一步对相关优化设置进行精细化优化与调整;'.PHP_EOL.'2、全球搜V6.0系统提供小语种页面精准校对翻译功能,用户可进一步对已翻译小语种页面进行人工翻译校对;'.PHP_EOL.'3、全球搜V6.0系统支持绑定Facebook、LinkedIn、X(原Twitter)等社媒账号,可一键同步转发网站上发布的产品和新闻至社媒账号动态,建议用户用起来哦;'.PHP_EOL.'4、如用户有较丰富的企业、产品、服务相关视频素材,全球搜建议用户及时创建YouTube主页,并在YouTube和网站相关网页上同步发布视频;';
290 - $message = "【全球搜V6.0周报】- 项目ID:" . PHP_EOL . $content . PHP_EOL . $tips; 289 + $message = "【全球搜V6.0周报】" . PHP_EOL . $content . PHP_EOL . $tips;
291 $param = [ 290 $param = [
292 'project_id'=>$project_id, 291 'project_id'=>$project_id,
293 'friend_id'=>$friend_id, 292 'friend_id'=>$friend_id,
@@ -1174,3 +1174,41 @@ function getDeployOptimize($project_id){ @@ -1174,3 +1174,41 @@ function getDeployOptimize($project_id){
1174 return $info; 1174 return $info;
1175 } 1175 }
1176 1176
  1177 +
  1178 +/**
  1179 + * @remark :返回分页数据
  1180 + * @name :paginateArray
  1181 + * @author :lyh
  1182 + * @method :post
  1183 + * @time :2025/4/1 9:41
  1184 + */
  1185 +function paginateArray($array, $page = 1, $pageSize = 20) {
  1186 + $totalItems = count($array);
  1187 + $totalPages = ceil($totalItems / $pageSize);
  1188 + // 确保页码有效
  1189 + $page = max(1, min($page, $totalPages));
  1190 + $offset = ($page - 1) * $pageSize;
  1191 + $data = array_slice($array, $offset, $pageSize);
  1192 + return [
  1193 + 'list' => $data,
  1194 + 'page' => $page,
  1195 + 'size' => $pageSize,
  1196 + 'total_page' => $totalPages,
  1197 + 'total' => $totalItems,
  1198 + ];
  1199 +}
  1200 +
  1201 +/**
  1202 + * @remark :获取域名
  1203 + * @name :getDomain
  1204 + * @author :lyh
  1205 + * @method :post
  1206 + * @time :2025/4/3 16:19
  1207 + */
  1208 +function getDomain($url) {
  1209 + $parsedUrl = parse_url($url);
  1210 + return $parsedUrl['host'] ?? $url; // 如果解析失败,返回原始 URL
  1211 +}
  1212 +
  1213 +
  1214 +
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :AfterCountController.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/4/8 9:56
  8 + */
  9 +
  10 +namespace App\Http\Controllers\Aside\Optimize;
  11 +
  12 +use App\Enums\Common\Code;
  13 +use App\Http\Controllers\Aside\BaseController;
  14 +use App\Models\HomeCount\AfterCount;
  15 +
  16 +class AfterCountController extends BaseController
  17 +{
  18 + /**
  19 + * @remark :售后数据统计
  20 + * @name :getAfterCount
  21 + * @author :lyh
  22 + * @method :post
  23 + * @time :2025/3/27 17:21
  24 + */
  25 + public function getAfterCount(AfterCount $afterCount){
  26 + $list = $afterCount->lists($this->map,$this->page,$this->row);
  27 + $this->response('success',Code::SUCCESS,$list);
  28 + }
  29 +
  30 + /**
  31 + * @remark :获取当前售后数据详情
  32 + * @name :getAfterCountInfo
  33 + * @author :lyh
  34 + * @method :post
  35 + * @time :2025/4/8 9:56
  36 + */
  37 + public function getAfterCountInfo(AfterCount $afterCount){
  38 + $this->request->validate([
  39 + 'id' => 'required',
  40 + ], [
  41 + 'id.required' => 'id不能为空',
  42 + ]);
  43 + $info = $afterCount->read($this->map,['id','data']);
  44 + $info['data'] = json_decode($info['data'],true);
  45 + $this->response('success',Code::SUCCESS,$info);
  46 + }
  47 +}
@@ -67,6 +67,7 @@ class OnlineController extends BaseController @@ -67,6 +67,7 @@ class OnlineController extends BaseController
67 'gl_project.is_upgrade AS is_upgrade', 67 'gl_project.is_upgrade AS is_upgrade',
68 'gl_project_online_check.id AS online_check_id', 68 'gl_project_online_check.id AS online_check_id',
69 'gl_project_online_check.question AS question', 69 'gl_project_online_check.question AS question',
  70 + 'gl_project_online_check.go_question AS go_question',
70 'gl_project_online_check.optimist_status AS optimist_status', 71 'gl_project_online_check.optimist_status AS optimist_status',
71 'gl_project_online_check.qa_status AS qa_status', 72 'gl_project_online_check.qa_status AS qa_status',
72 'gl_project_payment.amount AS amount', 73 'gl_project_payment.amount AS amount',
@@ -110,7 +111,8 @@ class OnlineController extends BaseController @@ -110,7 +111,8 @@ class OnlineController extends BaseController
110 $item['optimize_assist'] = $manageModel->getName($item['optimize_assist_mid']); 111 $item['optimize_assist'] = $manageModel->getName($item['optimize_assist_mid']);
111 $item['optimize_tech'] = $manageModel->getName($item['optimize_tech_mid']); 112 $item['optimize_tech'] = $manageModel->getName($item['optimize_tech_mid']);
112 $item['quality_mid_name'] = $manageModel->getName($item['quality_mid']); 113 $item['quality_mid_name'] = $manageModel->getName($item['quality_mid']);
113 - $item['plan'] = Project::planMap()[$item['plan']]; 114 + $plan = Project::planMap();
  115 + $item['plan'] = $plan[$item['plan']] ?? 0;
114 $item['created_at'] = date('Y年m月d日', strtotime($item['created_at'])); 116 $item['created_at'] = date('Y年m月d日', strtotime($item['created_at']));
115 $item['autologin_code'] = getAutoLoginCode($item['id']); 117 $item['autologin_code'] = getAutoLoginCode($item['id']);
116 $item['product_num'] = $data['product'] ?? 0; 118 $item['product_num'] = $data['product'] ?? 0;
@@ -147,6 +147,8 @@ class OptimizeController extends BaseController @@ -147,6 +147,8 @@ class OptimizeController extends BaseController
147 $data = APublicModel::getNumByProjectId($item['id']); 147 $data = APublicModel::getNumByProjectId($item['id']);
148 } 148 }
149 $manageModel = new ManageHr(); 149 $manageModel = new ManageHr();
  150 + $plan = Project::planMap();
  151 + $seo_plan = Project::seoMap();
150 $item['channel'] = Channel::getChannelText($item['channel']['user_id'] ?? 0); 152 $item['channel'] = Channel::getChannelText($item['channel']['user_id'] ?? 0);
151 $item['build_leader'] = $manageModel->getName($item['leader_mid']); 153 $item['build_leader'] = $manageModel->getName($item['leader_mid']);
152 $item['build_manager'] = $manageModel->getName($item['manager_mid']); 154 $item['build_manager'] = $manageModel->getName($item['manager_mid']);
@@ -157,7 +159,8 @@ class OptimizeController extends BaseController @@ -157,7 +159,8 @@ class OptimizeController extends BaseController
157 $item['optimize_assist'] = $manageModel->getName($item['optimize_assist_mid']); 159 $item['optimize_assist'] = $manageModel->getName($item['optimize_assist_mid']);
158 $item['optimize_tech'] = $manageModel->getName($item['optimize_tech_mid']); 160 $item['optimize_tech'] = $manageModel->getName($item['optimize_tech_mid']);
159 $item['quality_mid_name'] = $manageModel->getName($item['quality_mid']); 161 $item['quality_mid_name'] = $manageModel->getName($item['quality_mid']);
160 - $item['plan'] = Project::planMap()[$item['plan']]; 162 + $item['plan'] = $plan[$item['plan']] ?? 0;
  163 + $item['seo_plan'] = $seo_plan[$item['plan']] ?? 0;
161 $item['created_at'] = date('Y年m月d日', strtotime($item['cooperate_date'])); 164 $item['created_at'] = date('Y年m月d日', strtotime($item['cooperate_date']));
162 $item['autologin_code'] = getAutoLoginCode($item['id']); 165 $item['autologin_code'] = getAutoLoginCode($item['id']);
163 $item['domain'] = 'https://'.$item['domain'].'/'; 166 $item['domain'] = 'https://'.$item['domain'].'/';
@@ -213,6 +216,7 @@ class OptimizeController extends BaseController @@ -213,6 +216,7 @@ class OptimizeController extends BaseController
213 'gl_project_deploy_build.tech_mid AS tech_mid', 216 'gl_project_deploy_build.tech_mid AS tech_mid',
214 'gl_project_deploy_build.test_domain AS test_domain', 217 'gl_project_deploy_build.test_domain AS test_domain',
215 'gl_project_deploy_build.plan AS plan', 218 'gl_project_deploy_build.plan AS plan',
  219 + 'gl_project_deploy_build.seo_plan AS seo_plan',
216 'gl_project_deploy_optimize.dept_id AS optimize_dept_id', 220 'gl_project_deploy_optimize.dept_id AS optimize_dept_id',
217 'gl_project_deploy_optimize.manager_mid AS optimize_manager_mid', 221 'gl_project_deploy_optimize.manager_mid AS optimize_manager_mid',
218 'gl_project_deploy_optimize.optimist_mid AS optimize_optimist_mid', 222 'gl_project_deploy_optimize.optimist_mid AS optimize_optimist_mid',
@@ -246,7 +250,10 @@ class OptimizeController extends BaseController @@ -246,7 +250,10 @@ class OptimizeController extends BaseController
246 $query = $query->where('gl_project.title','like','%'.$this->map['title'].'%'); 250 $query = $query->where('gl_project.title','like','%'.$this->map['title'].'%');
247 } 251 }
248 if(isset($this->map['site_status'])){ 252 if(isset($this->map['site_status'])){
249 - $query = $query->where('gl_project.site_status',$this->map['site_status']); 253 + $query = $query->where('gl_project_deploy_build.site_status',$this->map['site_status']);
  254 + }
  255 + if(isset($this->map['seo_plan'])){
  256 + $query = $query->where('gl_project_deploy_build.seo_plan',$this->map['seo_plan']);
250 } 257 }
251 if(isset($this->map['main_lang_id'])){ 258 if(isset($this->map['main_lang_id'])){
252 $query = $query->where('gl_project.main_lang_id',$this->map['main_lang_id']); 259 $query = $query->where('gl_project.main_lang_id',$this->map['main_lang_id']);
@@ -484,7 +491,12 @@ class OptimizeController extends BaseController @@ -484,7 +491,12 @@ class OptimizeController extends BaseController
484 $this->fail('请先设置域名'); 491 $this->fail('请先设置域名');
485 } 492 }
486 $domain = 'https://' . $domainInfo['domain'] . '/'; 493 $domain = 'https://' . $domainInfo['domain'] . '/';
487 - $data = []; 494 + $data = [
  495 + 'ai_blog' => [],
  496 + 'product' => [],
  497 + 'product_category'=>[],
  498 + 'product_keyword' => [],
  499 + ];
488 ProjectServer::useProject($this->param['project_id']); 500 ProjectServer::useProject($this->param['project_id']);
489 $productModel = new Product(); 501 $productModel = new Product();
490 $this->processChunkedList($productModel, ['status' => $productModel::STATUS_ON], ['id', 'title', 'route'], $domain, $data, 'product'); 502 $this->processChunkedList($productModel, ['status' => $productModel::STATUS_ON], ['id', 'title', 'route'], $domain, $data, 'product');
@@ -581,15 +593,5 @@ class OptimizeController extends BaseController @@ -581,15 +593,5 @@ class OptimizeController extends BaseController
581 $this->response('success',Code::SUCCESS,$resultData); 593 $this->response('success',Code::SUCCESS,$resultData);
582 } 594 }
583 595
584 - /**  
585 - * @remark :售后数据统计  
586 - * @name :getAfterCount  
587 - * @author :lyh  
588 - * @method :post  
589 - * @time :2025/3/27 17:21  
590 - */  
591 - public function getAfterCount(AfterCount $afterCount){  
592 - $list = $afterCount->lists($this->map,$this->page,$this->row);  
593 - $this->response('success',Code::SUCCESS,$list);  
594 - } 596 +
595 } 597 }
@@ -292,6 +292,9 @@ class ProjectController extends BaseController @@ -292,6 +292,9 @@ class ProjectController extends BaseController
292 if(isset($this->map['plan'])){ 292 if(isset($this->map['plan'])){
293 $query = $query->where('gl_project_deploy_build.plan',$this->map['plan']); 293 $query = $query->where('gl_project_deploy_build.plan',$this->map['plan']);
294 } 294 }
  295 + if(isset($this->map['seo_plan'])){
  296 + $query = $query->where('gl_project_deploy_build.seo_plan',$this->map['seo_plan']);
  297 + }
295 if(isset($this->map['site_status'])){ 298 if(isset($this->map['site_status'])){
296 $query = $query->where('gl_project.site_status',$this->map['site_status']); 299 $query = $query->where('gl_project.site_status',$this->map['site_status']);
297 } 300 }
@@ -415,7 +418,10 @@ class ProjectController extends BaseController @@ -415,7 +418,10 @@ class ProjectController extends BaseController
415 $item['optimize_assist'] = $manageModel->getName($item['optimize_assist_mid']); 418 $item['optimize_assist'] = $manageModel->getName($item['optimize_assist_mid']);
416 $item['optimize_tech'] = $manageModel->getName($item['optimize_tech_mid']); 419 $item['optimize_tech'] = $manageModel->getName($item['optimize_tech_mid']);
417 $item['quality_mid_name'] = $manageModel->getName($item['quality_mid']); 420 $item['quality_mid_name'] = $manageModel->getName($item['quality_mid']);
418 - $item['plan'] = Project::planMap()[$item['plan']]; 421 + $planMap = Project::planMap();
  422 + $seoPlanMap = Project::seoMap();
  423 + $item['plan'] = $planMap[$item['plan']] ?? '';
  424 + $item['seo_plan'] = $seoPlanMap[$item['seo_plan']] ?? '';
419 $item['created_at'] = date('Y年m月d日', strtotime($item['cooperate_date'])); 425 $item['created_at'] = date('Y年m月d日', strtotime($item['cooperate_date']));
420 $item['autologin_code'] = getAutoLoginCode($item['id']); 426 $item['autologin_code'] = getAutoLoginCode($item['id']);
421 $domainModel = new DomainInfo(); 427 $domainModel = new DomainInfo();
@@ -67,6 +67,7 @@ class RenewProjectController extends BaseController @@ -67,6 +67,7 @@ class RenewProjectController extends BaseController
67 }else{ 67 }else{
68 $map['type'] = $param['type']; 68 $map['type'] = $param['type'];
69 } 69 }
  70 + $map['extend_type'] = 0;
70 $map['remain_day'] = ['<=',15]; 71 $map['remain_day'] = ['<=',15];
71 return $map; 72 return $map;
72 } 73 }
@@ -215,7 +215,7 @@ class CNoticeController extends BaseController @@ -215,7 +215,7 @@ class CNoticeController extends BaseController
215 $project_id = $this->user['project_id']; 215 $project_id = $this->user['project_id'];
216 $type = intval($request->input('type', 1)); 216 $type = intval($request->input('type', 1));
217 $route = intval($request->input('page', 1)); 217 $route = intval($request->input('page', 1));
218 - if($type == 2 && in_array($route,[4,6])){ 218 + if(($this->user['is_upgrade'] == 0) && ($type == 2) && in_array($route,[4,6])){
219 $this->fail('聚合页翻译请联系管理员'); 219 $this->fail('聚合页翻译请联系管理员');
220 } 220 }
221 $url = $request->input('url', []); 221 $url = $request->input('url', []);
@@ -65,11 +65,11 @@ class GoogleKeywordInsightController extends BaseController @@ -65,11 +65,11 @@ class GoogleKeywordInsightController extends BaseController
65 $detailModel = new GoogleKeywordInsightDetail(); 65 $detailModel = new GoogleKeywordInsightDetail();
66 $resultData = []; 66 $resultData = [];
67 if(!empty($array)){ 67 if(!empty($array)){
68 - $resultData = $this->paginateArray($array,$this->page,$this->row); 68 + $resultData = paginateArray($array,$this->page,$this->row);
69 $detailList = $detailModel->list(['search'=>['in',$resultData['list']]]); 69 $detailList = $detailModel->list(['search'=>['in',$resultData['list']]]);
70 foreach ($resultData['list'] as $key => $item){ 70 foreach ($resultData['list'] as $key => $item){
71 $result['keyword'] = $item; 71 $result['keyword'] = $item;
72 - $searchKeyword = $this->getSearchDetail($item,$detailList); 72 + $searchKeyword = $detailModel->getSearchDetail($item,$detailList);
73 if($searchKeyword === false){ 73 if($searchKeyword === false){
74 $result['data'] = []; 74 $result['data'] = [];
75 }else{ 75 }else{
@@ -101,44 +101,4 @@ class GoogleKeywordInsightController extends BaseController @@ -101,44 +101,4 @@ class GoogleKeywordInsightController extends BaseController
101 $this->response('success',Code::SUCCESS,$data); 101 $this->response('success',Code::SUCCESS,$data);
102 } 102 }
103 103
104 - /**  
105 - * @remark :查看当前数据是否存在数组中  
106 - * @name :getSearchDetail  
107 - * @author :lyh  
108 - * @method :post  
109 - * @time :2025/4/1 9:56  
110 - */  
111 - public function getSearchDetail($keyword,$detailList){  
112 - if(!empty($detailList)){  
113 - foreach ($detailList as $value){  
114 - if($keyword == $value['search']){  
115 - return $value;  
116 - }  
117 - }  
118 - }  
119 - return [];  
120 - }  
121 -  
122 - /**  
123 - * @remark :返回分页数据  
124 - * @name :paginateArray  
125 - * @author :lyh  
126 - * @method :post  
127 - * @time :2025/4/1 9:41  
128 - */  
129 - public function paginateArray($array, $page = 1, $pageSize = 20) {  
130 - $totalItems = count($array);  
131 - $totalPages = ceil($totalItems / $pageSize);  
132 - // 确保页码有效  
133 - $page = max(1, min($page, $totalPages));  
134 - $offset = ($page - 1) * $pageSize;  
135 - $data = array_slice($array, $offset, $pageSize);  
136 - return [  
137 - 'list' => $data,  
138 - 'page' => $page,  
139 - 'size' => $pageSize,  
140 - 'total_page' => $totalPages,  
141 - 'total' => $totalItems,  
142 - ];  
143 - }  
144 } 104 }
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :GoogleLinkController.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/4/3 15:05
  8 + */
  9 +
  10 +namespace App\Http\Controllers\Bside\GoogleKeyword;
  11 +
  12 +use App\Enums\Common\Code;
  13 +use App\Http\Controllers\Bside\BaseController;
  14 +use App\Models\GoogleSearch\GoogleLink;
  15 +use App\Services\GoogleLinkService;
  16 +
  17 +class GoogleLinkController extends BaseController
  18 +{
  19 + /**
  20 + * @remark :外链数据
  21 + * @name :getLink
  22 + * @author :lyh
  23 + * @method :post
  24 + * @time :2025/4/3 16:09
  25 + */
  26 + public function getLink(){
  27 + $linkModel = new GoogleLink();
  28 + $lists = $linkModel->lists($this->map,$this->page,$this->row,'id',['url','moz_da','status','google_search','date','project_id','domain']);
  29 + if(empty($lists['list'])){
  30 + $linkService = new GoogleLinkService();
  31 + $data = $linkService->linkPageData($this->user['domain'],$this->user['project_id']);
  32 + $lists = paginateArray($data,$this->page,$this->row);
  33 + }
  34 + $lists['y_total'] = $linkModel->counts(['status'=>1]);
  35 + $lists['n_total'] = $linkModel->counts(['status'=>0]);
  36 + $this->response('success',Code::SUCCESS,$lists);
  37 + }
  38 +
  39 +
  40 +}
@@ -37,7 +37,7 @@ class GoogleSearchController extends BaseController @@ -37,7 +37,7 @@ class GoogleSearchController extends BaseController
37 //查询详情数据 37 //查询详情数据
38 $searchDetailModel = new GoogleSearchDetail(); 38 $searchDetailModel = new GoogleSearchDetail();
39 $this->map['project_id']= 711; 39 $this->map['project_id']= 711;
40 - $data = $searchDetailModel->lists($this->map,$this->page,$this->row,'impressions'); 40 + $data = $searchDetailModel->lists($this->map,$this->page,$this->row,'clicks',['keys','click_rate','impressions_rate']);
41 if(!empty($data)){ 41 if(!empty($data)){
42 if($this->param['type'] == 'country'){ 42 if($this->param['type'] == 'country'){
43 $codeCountryModel = new GoogleCodeCountry(); 43 $codeCountryModel = new GoogleCodeCountry();
@@ -26,6 +26,10 @@ class ChatController extends BaseController @@ -26,6 +26,10 @@ class ChatController extends BaseController
26 */ 26 */
27 public function list(Chat $chat){ 27 public function list(Chat $chat){
28 $list = $chat->lists(['user_id'=>$this->user['id'],'status'=>1],$this->page,$this->row); 28 $list = $chat->lists(['user_id'=>$this->user['id'],'status'=>1],$this->page,$this->row);
  29 + $chatItem = new ChatItem();
  30 + foreach ($list as $k => $v){
  31 + $chatItem->orderBy('id', 'desc')->first();
  32 + }
29 $this->response('success',Code::SUCCESS,$list); 33 $this->response('success',Code::SUCCESS,$list);
30 } 34 }
31 35
@@ -78,4 +82,23 @@ class ChatController extends BaseController @@ -78,4 +82,23 @@ class ChatController extends BaseController
78 $data = $chat->edit(['status'=>0],['id'=>$this->param['id']]); 82 $data = $chat->edit(['status'=>0],['id'=>$this->param['id']]);
79 $this->response('success',Code::SUCCESS,$data); 83 $this->response('success',Code::SUCCESS,$data);
80 } 84 }
  85 +
  86 + /**
  87 + * @remark :修改标题
  88 + * @name :saveChat
  89 + * @author :lyh
  90 + * @method :post
  91 + * @time :2025/4/7 11:15
  92 + */
  93 + public function saveChat(Chat $chat){
  94 + $this->request->validate([
  95 + 'id'=>['required'],
  96 + 'input_content'=>['required'],
  97 + ],[
  98 + 'id.required' => 'id不能为空',
  99 + 'input_content.required' => '标题不能为空',
  100 + ]);
  101 + $data = $chat->edit(['input_content'=>$this->param['input_content']],['id'=>$this->param['id']]);
  102 + $this->response('success',Code::SUCCESS,$data);
  103 + }
81 } 104 }
@@ -152,7 +152,7 @@ class LoginController extends BaseController @@ -152,7 +152,7 @@ class LoginController extends BaseController
152 ],[ 152 ],[
153 'str.required' => '翻译字符串不能为空', 153 'str.required' => '翻译字符串不能为空',
154 ]); 154 ]);
155 - $str = Translate::tran($this->param['str'], 'en') ?? ''; 155 + $str = Translate::tran($this->param['str'], $this->param['language'] ?? 'en') ?? '';
156 if(is_array($str)){ 156 if(is_array($str)){
157 $str = $str[0]; 157 $str = $str[0];
158 } 158 }
@@ -201,6 +201,40 @@ class ProjectLogic extends BaseLogic @@ -201,6 +201,40 @@ class ProjectLogic extends BaseLogic
201 } 201 }
202 202
203 /** 203 /**
  204 + * @remark :保存上线审核问题
  205 + * @name :saveOnlineCheck
  206 + * @author :lyh
  207 + * @method :post
  208 + * @time :2025/4/3 16:41
  209 + */
  210 + public function saveOnlineCheck($project_id,$optimist_mid,$quality_mid,$question,$go_question){
  211 + if(($optimist_mid == 0) || ($quality_mid == 0)){
  212 + $this->fail('请先选择优化师和品控,在提交审核');
  213 + }
  214 + $onlineCheckModel = new OnlineCheck();
  215 + $onlineInfo = $onlineCheckModel->read(['project_id'=>$project_id]);
  216 + if($onlineInfo === false){
  217 + $data = [
  218 + 'project_id' => $project_id,
  219 + 'created_manage_id' => $this->manager['id'],
  220 + 'optimist_mid' => $optimist_mid,
  221 + 'qa_mid' => $quality_mid,
  222 + 'created_at'=>date('Y-m-d H:i:s'),
  223 + 'question'=>$question,
  224 + 'go_question'=>$go_question
  225 + ];
  226 + $onlineCheckModel->addReturnId($data);
  227 + }else{
  228 + $data = [
  229 + 'question'=>$question,
  230 + 'go_question'=>$go_question
  231 + ];
  232 + $onlineCheckModel->edit($data,['project_id'=>$project_id]);
  233 + }
  234 + return true;
  235 + }
  236 +
  237 + /**
204 * @remark :开启白帽验证产数 238 * @remark :开启白帽验证产数
205 * @name :checkAiBlog 239 * @name :checkAiBlog
206 * @author :lyh 240 * @author :lyh
@@ -451,7 +485,7 @@ class ProjectLogic extends BaseLogic @@ -451,7 +485,7 @@ class ProjectLogic extends BaseLogic
451 } 485 }
452 486
453 /** 487 /**
454 - * @remark :保存seo白帽类型 488 + * @remark :保存seo白帽类型,上线保存一条审核记录,
455 * @name :saveSeoPlan 489 * @name :saveSeoPlan
456 * @author :lyh 490 * @author :lyh
457 * @method :post 491 * @method :post
@@ -461,22 +495,28 @@ class ProjectLogic extends BaseLogic @@ -461,22 +495,28 @@ class ProjectLogic extends BaseLogic
461 $onlineCheckModel = new OnlineCheck(); 495 $onlineCheckModel = new OnlineCheck();
462 if(($plan == Project::TYPE_ZERO) && ($seo_plan == Project::TYPE_ONE) && ($type == Project::TYPE_TWO || $type == Project::TYPE_THREE)){ 496 if(($plan == Project::TYPE_ZERO) && ($seo_plan == Project::TYPE_ONE) && ($type == Project::TYPE_TWO || $type == Project::TYPE_THREE)){
463 $onlineInfo = $onlineCheckModel->read(['project_id'=>$project_id]); 497 $onlineInfo = $onlineCheckModel->read(['project_id'=>$project_id]);
  498 + $data = [
  499 + 'project_id' => $project_id,
  500 + 'created_manage_id' => $this->manager['id'],
  501 + 'optimist_mid' => $optimist_mid,
  502 + 'optimist_check_time'=>date('Y-m-d H:i:s'),
  503 + 'optimist_status'=>1,
  504 + 'qa_mid' => $quality_mid,
  505 + 'qa_check_time'=>date('Y-m-d H:i:s'),
  506 + 'qa_status'=>1,
  507 + 'created_at'=>date('Y-m-d H:i:s'),
  508 + ];
464 if($onlineInfo === false){ 509 if($onlineInfo === false){
465 if(empty($optimist_mid) || empty($quality_mid)){ 510 if(empty($optimist_mid) || empty($quality_mid)){
466 - $this->fail('请选择优化师及品控'); 511 + $this->fail('自动提交审核,请选择优化师及品控');
467 } 512 }
468 - $data = [  
469 - 'project_id' => $project_id,  
470 - 'created_manage_id' => $this->manager['id'],  
471 - 'optimist_mid' => $optimist_mid,  
472 - 'optimist_check_time'=>date('Y-m-d H:i:s'),  
473 - 'optimist_status'=>1,  
474 - 'qa_mid' => $quality_mid,  
475 - 'qa_check_time'=>date('Y-m-d H:i:s'),  
476 - 'qa_status'=>1,  
477 - 'created_at'=>date('Y-m-d H:i:s'),  
478 - ];  
479 $onlineCheckModel->addReturnId($data); 513 $onlineCheckModel->addReturnId($data);
  514 + }else{
  515 + $onlineCheckModel->edit($data,['project_id'=>$project_id]);
  516 + }
  517 + $this->param['status'] = Project::STATUS_ONE;
  518 + if(empty($this->param['uptime'])){
  519 + $this->param['uptime'] = date('Y-m-d H:i:s');
480 } 520 }
481 } 521 }
482 return true; 522 return true;
@@ -70,6 +70,11 @@ class ChatLogic extends BaseLogic @@ -70,6 +70,11 @@ class ChatLogic extends BaseLogic
70 } 70 }
71 $data = ['message' => $message]; 71 $data = ['message' => $message];
72 $stream = $gptService->get_ai_chat($data); // 获取流 72 $stream = $gptService->get_ai_chat($data); // 获取流
  73 + // 允许跨域访问
  74 + header('Access-Control-Allow-Origin: *');
  75 + header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
  76 + header('Access-Control-Allow-Headers: Content-Type, Authorization');
  77 +
73 header('Content-Type: text/event-stream'); 78 header('Content-Type: text/event-stream');
74 header('Cache-Control: no-cache'); 79 header('Cache-Control: no-cache');
75 header('Connection: keep-alive'); 80 header('Connection: keep-alive');
@@ -89,7 +94,7 @@ class ChatLogic extends BaseLogic @@ -89,7 +94,7 @@ class ChatLogic extends BaseLogic
89 if (json_last_error() === JSON_ERROR_NONE) { 94 if (json_last_error() === JSON_ERROR_NONE) {
90 if (isset($jsonData['text'])) { 95 if (isset($jsonData['text'])) {
91 $aiResponse .= $jsonData['text']; 96 $aiResponse .= $jsonData['text'];
92 - echo $gptService->en_sse_data(trim($jsonData['text'])); 97 + echo $gptService->en_sse_data($jsonData['text']);
93 ob_flush(); 98 ob_flush();
94 flush(); 99 flush();
95 } 100 }
@@ -116,7 +121,7 @@ class ChatLogic extends BaseLogic @@ -116,7 +121,7 @@ class ChatLogic extends BaseLogic
116 //创建一个会话 121 //创建一个会话
117 $saveData = [ 122 $saveData = [
118 'user_id'=>$this->user['id'], 123 'user_id'=>$this->user['id'],
119 - 'input_content'=>$message, 124 + 'input_content'=>mb_substr($message, 0, 50, "UTF-8").'...',
120 ]; 125 ];
121 return $this->model->addReturnId($saveData); 126 return $this->model->addReturnId($saveData);
122 } 127 }
@@ -136,6 +141,9 @@ class ChatLogic extends BaseLogic @@ -136,6 +141,9 @@ class ChatLogic extends BaseLogic
136 'chat_id'=>$id, 141 'chat_id'=>$id,
137 'content'=>$message, 142 'content'=>$message,
138 ]; 143 ];
139 - return $this->itemModel->addReturnId($saveData); 144 + //同时更改主任务
  145 + $this->itemModel->addReturnId($saveData);
  146 + $data = ['last_created_at'=>date('Y-m-d H:i:s'),'last_input_content'=>mb_substr($message, 0, 50, "UTF-8").'...'];
  147 + return $this->model->edit($data,['id'=>$id]);
140 } 148 }
141 } 149 }
@@ -81,13 +81,16 @@ class RankDataLogic extends BaseLogic @@ -81,13 +81,16 @@ class RankDataLogic extends BaseLogic
81 } 81 }
82 $g_top_plan['day'] = $g_top_plan['service_day'] - $g_top_plan['is_compliance']; 82 $g_top_plan['day'] = $g_top_plan['service_day'] - $g_top_plan['is_compliance'];
83 } 83 }
  84 + $plan = Project::planMap();
  85 + $seo_plan = Project::seoMap();
84 //项目信息 86 //项目信息
85 $data['project'] = [ 87 $data['project'] = [
86 'company' => $project['company'], 88 'company' => $project['company'],
87 'domain' => $domain_info['domain'] ?? '', 89 'domain' => $domain_info['domain'] ?? '',
88 'domain_info' => $domain_info['domain_info'] ?? '', 90 'domain_info' => $domain_info['domain_info'] ?? '',
89 'cert_info' => $domain_info['cert_info'] ?? '', 91 'cert_info' => $domain_info['cert_info'] ?? '',
90 - 'plan' => Project::planMap()[$project['deploy_build']['plan']], 92 + 'plan' => $plan[$project['deploy_build']['plan']] ?? 0,
  93 + 'seo_plan' => $seo_plan[$project['deploy_build']['seo_plan']] ?? 0,
91 'keyword_num' => $project['deploy_build']['keyword_num'], 94 'keyword_num' => $project['deploy_build']['keyword_num'],
92 'compliance_day' => $project['finish_remain_day'] ?? 0, 95 'compliance_day' => $project['finish_remain_day'] ?? 0,
93 'remain_day' => $project['remain_day'], 96 'remain_day' => $project['remain_day'],
@@ -490,7 +493,8 @@ class RankDataLogic extends BaseLogic @@ -490,7 +493,8 @@ class RankDataLogic extends BaseLogic
490 $without_extension_project_ids = [658]; //是否达标只统计主词的 493 $without_extension_project_ids = [658]; //是否达标只统计主词的
491 $extension_project_ids = [354]; //扩展词也到达标的 494 $extension_project_ids = [354]; //扩展词也到达标的
492 $compliance_project_ids = [2163,257,823]; //直接达标处理的 495 $compliance_project_ids = [2163,257,823]; //直接达标处理的
493 - $ceaseProjectId = [47, 354, 378, 649, 1226, 1283, 1703, 1893, 2066,2974];//暂停项目id 496 + $ceaseProjectId = [47, 354, 378, 649, 1226, 1283, 1703, 1893, 2066];//暂停的项目
  497 + $uptimeProjectId = [1434,1812,276,2414,2974];//按上线时间统计的项目
494 //一个项目多个api_no 498 //一个项目多个api_no
495 $multiple_api_no_project_ids = [ 499 $multiple_api_no_project_ids = [
496 2104 => [ 500 2104 => [
@@ -565,23 +569,27 @@ class RankDataLogic extends BaseLogic @@ -565,23 +569,27 @@ class RankDataLogic extends BaseLogic
565 //项目表更新 569 //项目表更新
566 if (($model->updated_date != date('Y-m-d') || empty($model_is_compliance)) && !$lang) { 570 if (($model->updated_date != date('Y-m-d') || empty($model_is_compliance)) && !$lang) {
567 $compliance_day = Project::where(['id' => $project_id])->value('finish_remain_day') ?: 0; 571 $compliance_day = Project::where(['id' => $project_id])->value('finish_remain_day') ?: 0;
568 - if(!in_array($project_id,$ceaseProjectId)){ 572 + if(!in_array($project_id,$ceaseProjectId)){//不是暂停的项目
569 if($compliance_day == 0){//达标天数为0并当天达标 记录当前达标时间 573 if($compliance_day == 0){//达标天数为0并当天达标 记录当前达标时间
570 DeployOptimize::where(['project_id'=>$project_id])->update(['first_compliance_time'=>date('Y-m-d')]); 574 DeployOptimize::where(['project_id'=>$project_id])->update(['first_compliance_time'=>date('Y-m-d')]);
571 } 575 }
572 - //多api_no项目 要api_no都分别达标才算  
573 - if(in_array($project_id, array_keys($multiple_api_no_project_ids))){  
574 - $api_nos = array_keys($multiple_api_no_project_ids[$project_id]);  
575 - //今天其他api_no是否都达标了  
576 - $count = RankData::where('project_id', $project_id)->whereIn('api_no', $api_nos)->where('api_no', '<>', $api_no)->where('updated_date', date('Y-m-d'))  
577 - ->where('is_compliance', 1)->count();  
578 - if($count == count($api_nos) - 1){ 576 + if(in_array($project_id,$uptimeProjectId)){//直接按上线时间统计的项目
  577 + Project::where('id', $project_id)->update(['is_remain_today' => 1, 'finish_remain_day' => $compliance_day + 1]);
  578 + }else{
  579 + //多api_no项目 要api_no都分别达标才算
  580 + if(in_array($project_id, array_keys($multiple_api_no_project_ids))){
  581 + $api_nos = array_keys($multiple_api_no_project_ids[$project_id]);
  582 + //今天其他api_no是否都达标了
  583 + $count = RankData::where('project_id', $project_id)->whereIn('api_no', $api_nos)->where('api_no', '<>', $api_no)->where('updated_date', date('Y-m-d'))
  584 + ->where('is_compliance', 1)->count();
  585 + if($count == count($api_nos) - 1){
  586 + Project::where('id', $project_id)->update(['is_remain_today' => 1, 'finish_remain_day' => $compliance_day + 1]);
  587 + }
  588 + }else{
579 Project::where('id', $project_id)->update(['is_remain_today' => 1, 'finish_remain_day' => $compliance_day + 1]); 589 Project::where('id', $project_id)->update(['is_remain_today' => 1, 'finish_remain_day' => $compliance_day + 1]);
580 } 590 }
581 - }else{  
582 - Project::where('id', $project_id)->update(['is_remain_today' => 1, 'finish_remain_day' => $compliance_day + 1]); 591 + Log::channel('rank_data')->info('项目' . $project_id . '达标天数+1:' . ($compliance_day + 1));
583 } 592 }
584 - Log::channel('rank_data')->info('项目' . $project_id . '达标天数+1:' . ($compliance_day + 1));  
585 }else{ 593 }else{
586 Project::where('id', $project_id)->update(['is_remain_today' => 1, 'finish_remain_day' => $compliance_day]); 594 Project::where('id', $project_id)->update(['is_remain_today' => 1, 'finish_remain_day' => $compliance_day]);
587 Log::channel('rank_data')->info('项目' . $project_id . '暂停项目达标天数不加:'. ($compliance_day)); 595 Log::channel('rank_data')->info('项目' . $project_id . '暂停项目达标天数不加:'. ($compliance_day));
@@ -261,7 +261,10 @@ class UserLoginLogic @@ -261,7 +261,10 @@ class UserLoginLogic
261 $info['from_order_id'] = $project['from_order_id'] ?? ''; 261 $info['from_order_id'] = $project['from_order_id'] ?? '';
262 $info['aicc'] = $project['aicc'] ?? ''; 262 $info['aicc'] = $project['aicc'] ?? '';
263 $info['hagro'] = $project['hagro'] ?? ''; 263 $info['hagro'] = $project['hagro'] ?? '';
264 - $info['plan'] = Project::planMap()[$project['deploy_build']['plan']]; 264 + $plan = Project::planMap();
  265 + $seo_plan = Project::seoMap();
  266 + $info['plan'] = $plan[$project['deploy_build']['plan']] ?? 0;
  267 + $info['seo_plan'] = $seo_plan[$project['deploy_build']['seo_plan']] ?? 0;
265 $info['is_domain'] = empty($project['deploy_optimize']['domain']) ? 0 : 1; 268 $info['is_domain'] = empty($project['deploy_optimize']['domain']) ? 0 : 1;
266 $info['test_domain'] = $project['deploy_build']['test_domain'] ?? ''; 269 $info['test_domain'] = $project['deploy_build']['test_domain'] ?? '';
267 $info['domain'] = (!empty($project['deploy_optimize']['domain']) ? ((new DomainInfo())->getDomain($project['deploy_optimize']['domain'])) : ($project['deploy_build']['test_domain'] ?? '')); 270 $info['domain'] = (!empty($project['deploy_optimize']['domain']) ? ((new DomainInfo())->getDomain($project['deploy_optimize']['domain'])) : ($project['deploy_build']['test_domain'] ?? ''));
@@ -67,4 +67,22 @@ class GoogleKeywordInsightDetail extends Base @@ -67,4 +67,22 @@ class GoogleKeywordInsightDetail extends Base
67 ]; 67 ];
68 return $this->addReturnId($saveData); 68 return $this->addReturnId($saveData);
69 } 69 }
  70 +
  71 + /**
  72 + * @remark :查看当前数据是否存在数组中
  73 + * @name :getSearchDetail
  74 + * @author :lyh
  75 + * @method :post
  76 + * @time :2025/4/1 9:56
  77 + */
  78 + public function getSearchDetail($keyword,$detailList){
  79 + if(!empty($detailList)){
  80 + foreach ($detailList as $value){
  81 + if($keyword == $value['search']){
  82 + return $value;
  83 + }
  84 + }
  85 + }
  86 + return [];
  87 + }
70 } 88 }
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :GoogleLink.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/4/3 15:52
  8 + */
  9 +
  10 +namespace App\Models\GoogleSearch;
  11 +
  12 +use App\Models\Base;
  13 +
  14 +/**
  15 + * @remark :外链数据
  16 + * @name :GoogleLink
  17 + * @author :lyh
  18 + * @method :post
  19 + * @time :2025/4/3 15:53
  20 + */
  21 +class GoogleLink extends Base
  22 +{
  23 + protected $table = 'gl_google_link';
  24 +}
@@ -115,7 +115,6 @@ class Project extends Base @@ -115,7 +115,6 @@ class Project extends Base
115 12 => '俄语商务版', 115 12 => '俄语商务版',
116 14 => '俄语旗舰版', 116 14 => '俄语旗舰版',
117 13 => '体验版', 117 13 => '体验版',
118 - 15 => '白帽SEO方案',  
119 ]; 118 ];
120 } 119 }
121 120
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :GoogleLinkService.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/4/3 15:06
  8 + */
  9 +
  10 +namespace App\Services;
  11 +
  12 +use App\Models\GoogleSearch\GoogleLink;
  13 +
  14 +class GoogleLinkService
  15 +{
  16 + public $url = 'https://www.cmer.site/api/outlinks';
  17 +
  18 + /**
  19 + * @remark :只拉取1页数据
  20 + * @name :linkPageData
  21 + * @author :lyh
  22 + * @method :post
  23 + * @time :2025/4/3 15:54
  24 + */
  25 + public function linkPageData($domain,$project_id)
  26 + {
  27 + $domain = getDomain($domain);
  28 + // 第一次请求,获取总数
  29 + $param = [
  30 + 'domain' => $domain,
  31 + 'page' => 1,
  32 + 'pagesize' => 1, // 只拉取一条数据,获取 total
  33 + ];
  34 + $queryString = http_build_query($param);
  35 + $url = $this->url . '?' . $queryString;
  36 + $response = http_get($url);
  37 + if (!empty($response) && !empty($response['data']['total'])) {
  38 + // 计算总数并一次性获取所有数据
  39 + $param['pagesize'] = $response['data']['total'];
  40 + $queryString = http_build_query($param);
  41 + $url = $this->url . '?' . $queryString;
  42 + $response = http_get($url);
  43 + if (!empty($response['data']['data'])) {
  44 + return $this->saveLink($response['data']['data'],$project_id,$domain);// 批量插入
  45 + }
  46 + }
  47 + return false;
  48 + }
  49 + /**
  50 + * @remark :拉取所有数据
  51 + * @name :linkData
  52 + * @author :lyh
  53 + * @method :post
  54 + * @time :2025/4/3 15:55
  55 + */
  56 + public function linkData($domain,$project_id, $page = 1, $pagesize = 200)
  57 + {
  58 + $domain = getDomain($domain);
  59 + $param = [
  60 + 'domain' => $domain,
  61 + 'page' => $page,
  62 + 'pagesize' => $pagesize,
  63 + ];
  64 + do {
  65 + $queryString = http_build_query($param);
  66 + $url = $this->url . '?' . $queryString;
  67 + $response = http_get($url);
  68 + if (!empty($response) && !empty($response['data']['data'])) {
  69 + if (!empty($response['data']['data'])) {
  70 + $this->saveLink($response['data']['data'],$project_id,$domain);// 批量插入
  71 + }
  72 + $page++;
  73 + $param['page'] = $page; // 更新页码
  74 + } else {
  75 + break; // 遇到错误或空数据时跳出循环
  76 + }
  77 + } while ($page <= $response['data']['last_page']); // 循环直到拉取完所有页数据
  78 + return true;
  79 + }
  80 +
  81 + /**
  82 + * @remark :保存数据库
  83 + * @name :saveLink
  84 + * @author :lyh
  85 + * @method :post
  86 + * @time :2025/4/3 15:26
  87 + */
  88 + public function saveLink($data,$project_id,$domain){
  89 + $saveData = [];
  90 + foreach ($data as $val){
  91 + $timestamp = strtotime($val['created_at']);
  92 + $date = date('Y-m-d H:i:s', $timestamp ?? time());
  93 + $saveData[] = [
  94 + 'url'=>$val['url'],
  95 + 'moz_da'=>$val['mozDA'],
  96 + 'status'=>$val['status'],
  97 + 'google_search'=>$val['googlesearch'],
  98 + 'date'=>$date,
  99 + 'project_id'=>$project_id,
  100 + 'domain'=>$domain
  101 + ];
  102 + }
  103 + $linkModel = new GoogleLink();
  104 + $linkModel->insertAll($saveData);
  105 + return $saveData;
  106 + }
  107 +}
@@ -59,10 +59,6 @@ class GptService @@ -59,10 +59,6 @@ class GptService
59 * @time :2025/4/2 16:56 59 * @time :2025/4/2 16:56
60 */ 60 */
61 public function en_sse_data($body, string $type='text'){ 61 public function en_sse_data($body, string $type='text'){
62 - return 'data:'.json_encode([  
63 - 'id' => md5(is_array($body) ? json_encode($body) : $body),  
64 - 'data' => $body,  
65 - 'type' => $type  
66 - ],JSON_UNESCAPED_UNICODE)."\n\n"; 62 + return 'data:'.json_encode(['id' => md5(is_array($body) ? json_encode($body) : $body), 'data' => $body, 'type' => $type],JSON_UNESCAPED_UNICODE)."\n\n";
67 } 63 }
68 } 64 }
@@ -304,7 +304,8 @@ Route::middleware(['aloginauth'])->group(function () { @@ -304,7 +304,8 @@ Route::middleware(['aloginauth'])->group(function () {
304 Route::any('/saveMinorLanguages', [Aside\Optimize\OptimizeController::class, 'saveMinorLanguages'])->name('admin.optimize_saveMinorLanguages');//设置小语种监控开关 304 Route::any('/saveMinorLanguages', [Aside\Optimize\OptimizeController::class, 'saveMinorLanguages'])->name('admin.optimize_saveMinorLanguages');//设置小语种监控开关
305 Route::any('/editTranslateStatus', [Aside\Optimize\OptimizeController::class, 'editTranslateStatus'])->name('admin.optimize_editTranslateStatus');//设置robots开关 305 Route::any('/editTranslateStatus', [Aside\Optimize\OptimizeController::class, 'editTranslateStatus'])->name('admin.optimize_editTranslateStatus');//设置robots开关
306 Route::any('/getAnchorLink', [Aside\Optimize\OptimizeController::class, 'getAnchorLink'])->name('admin.optimize_getAnchorLink');//设置robots开关 306 Route::any('/getAnchorLink', [Aside\Optimize\OptimizeController::class, 'getAnchorLink'])->name('admin.optimize_getAnchorLink');//设置robots开关
307 - Route::any('/getAfterCount', [Aside\Optimize\OptimizeController::class, 'getAfterCount'])->name('admin.optimize_getAfterCount');//设置robots开关 307 + Route::any('/getAfterCount', [Aside\Optimize\AfterCountController::class, 'getAfterCount'])->name('admin.optimize_getAfterCount');//售后统计数据
  308 + Route::any('/getAfterCountInfo', [Aside\Optimize\AfterCountController::class, 'getAfterCountInfo'])->name('admin.optimize_getAfterCountInfo');//售后统计数据详情
308 }); 309 });
309 //生成关键字 310 //生成关键字
310 Route::prefix('create_keyword')->group(function () { 311 Route::prefix('create_keyword')->group(function () {
@@ -717,8 +717,13 @@ Route::middleware(['bloginauth'])->group(function () { @@ -717,8 +717,13 @@ Route::middleware(['bloginauth'])->group(function () {
717 Route::any('/', [\App\Http\Controllers\Bside\Gpt\ChatController::class, 'list'])->name('gpt_list'); 717 Route::any('/', [\App\Http\Controllers\Bside\Gpt\ChatController::class, 'list'])->name('gpt_list');
718 Route::any('/itemList', [\App\Http\Controllers\Bside\Gpt\ChatController::class, 'itemList'])->name('gpt_itemList'); 718 Route::any('/itemList', [\App\Http\Controllers\Bside\Gpt\ChatController::class, 'itemList'])->name('gpt_itemList');
719 Route::any('/del', [\App\Http\Controllers\Bside\Gpt\ChatController::class, 'del'])->name('gpt_del'); 719 Route::any('/del', [\App\Http\Controllers\Bside\Gpt\ChatController::class, 'del'])->name('gpt_del');
  720 + Route::any('/save', [\App\Http\Controllers\Bside\Gpt\ChatController::class, 'saveChat'])->name('gpt_save');
720 Route::any('/sendMessage', [\App\Http\Controllers\Bside\Gpt\ChatController::class, 'sendMessage'])->name('gpt_sendMessage'); 721 Route::any('/sendMessage', [\App\Http\Controllers\Bside\Gpt\ChatController::class, 'sendMessage'])->name('gpt_sendMessage');
721 }); 722 });
  723 +
  724 + Route::prefix('google_link')->group(function () {
  725 + Route::any('/', [\App\Http\Controllers\Bside\GoogleKeyword\GoogleLinkController::class,'getLink'])->name('google_link_getLink');
  726 + });
722 }); 727 });
723 //无需登录验证的路由组 728 //无需登录验证的路由组
724 Route::group([], function () { 729 Route::group([], function () {