作者 赵彬吉
@@ -51,12 +51,13 @@ class GeoQuestionRes extends Command @@ -51,12 +51,13 @@ class GeoQuestionRes extends Command
51 sleep(300); 51 sleep(300);
52 continue; 52 continue;
53 } 53 }
54 - $lock_key = "geo_task_lock:$task_id"; 54 + $lock_key = "geo_task_lock_" . $task_id;
55 if (!Redis::setnx($lock_key, 1)) { 55 if (!Redis::setnx($lock_key, 1)) {
56 $this->output("任务 $task_id 已被其他进程锁定,跳过"); 56 $this->output("任务 $task_id 已被其他进程锁定,跳过");
  57 + sleep(30); // 程序挂起, 避免最后一个任务 扫数据表和Redis
57 continue; 58 continue;
58 } 59 }
59 - Redis::expire($lock_key, 1200); // 1小时自动解锁 60 + Redis::expire($lock_key, 600); // 10自动解锁
60 $this->output('执行的任务ID:' . $task_id); 61 $this->output('执行的任务ID:' . $task_id);
61 $geoQuestionModel = new GeoQuestion(); 62 $geoQuestionModel = new GeoQuestion();
62 $taskInfo = $geoQuestionModel->read(['id'=>$task_id]); 63 $taskInfo = $geoQuestionModel->read(['id'=>$task_id]);
@@ -86,6 +87,7 @@ class GeoQuestionRes extends Command @@ -86,6 +87,7 @@ class GeoQuestionRes extends Command
86 $geoResultModel = new GeoQuestionResult(); 87 $geoResultModel = new GeoQuestionResult();
87 $geoLogModel = new GeoQuestionLog(); 88 $geoLogModel = new GeoQuestionLog();
88 foreach ($taskInfo['question'] as $question) { 89 foreach ($taskInfo['question'] as $question) {
  90 + Redis::expire($lock_key, 1200); // 一个问题执行时间可能会达到15-18分钟
89 $en_question = Translate::tran($question, 'zh') ?? ''; 91 $en_question = Translate::tran($question, 'zh') ?? '';
90 $this->output('项目ID:' . $taskInfo['project_id'] . ', 问题 开始:' . $question); 92 $this->output('项目ID:' . $taskInfo['project_id'] . ', 问题 开始:' . $question);
91 foreach ($platformsArr as $platform) { 93 foreach ($platformsArr as $platform) {
@@ -345,19 +347,28 @@ class GeoQuestionRes extends Command @@ -345,19 +347,28 @@ class GeoQuestionRes extends Command
345 $key = 'geo_task_list'; 347 $key = 'geo_task_list';
346 $task_id = Redis::rpop($key); 348 $task_id = Redis::rpop($key);
347 if(empty($task_id)){ 349 if(empty($task_id)){
348 - $project_ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)->where('next_time', '<=', date('Y-m-d'))  
349 - ->orderBy('next_time', 'asc')->pluck('project_id')->unique()->values()->toArray();  
350 - if(!empty($project_ids)){  
351 - foreach ($project_ids as $project_id){  
352 - $ids = GeoQuestion::where(['project_id' => $project_id, 'status' => GeoQuestion::STATUS_OPEN])->where('next_time', '<=', date('Y-m-d'))->pluck('id');  
353 - foreach ($ids as $id) {  
354 - //检查任务是否执行过  
355 - if (!Redis::exists("geo_task_lock:$id")) {  
356 - Redis::lpush($key, $id);  
357 - }  
358 - }  
359 - $task_id = Redis::rpop($key); 350 + $lock_key = 'geo_task_generation_lock';
  351 + $lock_ttl = 60; // 锁时间大于当前 锁功能执行时间
  352 + // 尝试获取锁,非阻塞方式
  353 + $lock = Redis::set($lock_key, 1, 'EX', $lock_ttl, 'NX');
  354 + if (empty($lock)){
  355 + return $task_id;
  356 + }
  357 + $project_ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)->where('next_time', '<=', date('Y-m-d'))->pluck('project_id')->unique()->values()->toArray();
  358 + if(FALSE == empty($project_ids)){
  359 + $ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)
  360 + ->whereIn('project_id', $project_ids)
  361 + ->where(function ($query){
  362 + $query->where('current_time', '!=', date('Y-m-d'))
  363 + ->orWhereNull('current_time');
  364 + })
  365 + ->orderBy('project_id', 'asc')
  366 + ->pluck('id');
  367 +
  368 + foreach ($ids as $id) {
  369 + Redis::lpush($key, $id);
360 } 370 }
  371 + $task_id = Redis::rpop($key);
361 } 372 }
362 } 373 }
363 return $task_id; 374 return $task_id;
@@ -5,14 +5,20 @@ @@ -5,14 +5,20 @@
5 * Date: 2025/10/27 5 * Date: 2025/10/27
6 * Time: 13:42 6 * Time: 13:42
7 */ 7 */
  8 +
8 namespace App\Console\Commands\Product; 9 namespace App\Console\Commands\Product;
9 10
10 use App\Console\Commands\Tdk\UpdateSeoTdk; 11 use App\Console\Commands\Tdk\UpdateSeoTdk;
  12 +use App\Models\Com\NoticeLog;
  13 +use App\Models\Com\UpdateNotify;
  14 +use App\Models\Domain\DomainInfo;
11 use App\Models\Product\Keyword; 15 use App\Models\Product\Keyword;
  16 +use App\Models\Project\DeployBuild;
12 use App\Models\Project\Project; 17 use App\Models\Project\Project;
13 use App\Services\ProjectServer; 18 use App\Services\ProjectServer;
14 use Illuminate\Console\Command; 19 use Illuminate\Console\Command;
15 use Illuminate\Support\Arr; 20 use Illuminate\Support\Arr;
  21 +use Illuminate\Support\Facades\Cache;
16 use Illuminate\Support\Str; 22 use Illuminate\Support\Str;
17 23
18 class SplicePrefix extends Command 24 class SplicePrefix extends Command
@@ -36,17 +42,36 @@ class SplicePrefix extends Command @@ -36,17 +42,36 @@ class SplicePrefix extends Command
36 */ 42 */
37 public function handle() 43 public function handle()
38 { 44 {
39 - #TODO 获取当日不达标项目, 检查关键词前缀拼接 45 + //获取当日不达标项目, 检查关键词前缀拼接
40 $project_ids = $this->getProject(); 46 $project_ids = $this->getProject();
41 if (empty($project_ids)) 47 if (empty($project_ids))
42 return true; 48 return true;
43 49
  50 + //获取已经拼接的项目id
  51 + $key = 'splice_prefix_project_ids';
  52 + $has_splice_ids = Cache::get($key) ?? [];
  53 +
44 foreach ($project_ids as $project_id) { 54 foreach ($project_ids as $project_id) {
45 if ($project_id == 1) 55 if ($project_id == 1)
46 continue; 56 continue;
  57 +
  58 + if (in_array($project_id, $has_splice_ids)) {
  59 + continue;
  60 + }
  61 +
47 $this->output('project start: ' . $project_id); 62 $this->output('project start: ' . $project_id);
  63 +
48 $this->bind($project_id); 64 $this->bind($project_id);
  65 +
  66 + //处理完后加入已拼接项目id集
  67 + array_push($has_splice_ids, $project_id);
  68 +
  69 + $this->output('project end: ' . $project_id);
49 } 70 }
  71 +
  72 + //更新已拼接项目id缓存
  73 + Cache::put($key, $has_splice_ids);
  74 +
50 return true; 75 return true;
51 } 76 }
52 77
@@ -56,129 +81,147 @@ class SplicePrefix extends Command @@ -56,129 +81,147 @@ class SplicePrefix extends Command
56 */ 81 */
57 public function bind($project_id) 82 public function bind($project_id)
58 { 83 {
59 - $project = ProjectServer::useProject($project_id);  
60 -  
61 - // 客户前缀  
62 - $tdk_class = new UpdateSeoTdk();  
63 - $info = $tdk_class->getDeployOptimize($project_id);  
64 - $fix_keyword = explode(",", $info['keyword_prefix']);  
65 - $fix_keyword = array_filter($fix_keyword);  
66 -  
67 - // 所有前缀  
68 - $all_prefixes = $tdk_class->getAllPrefix(1, $project_id);  
69 - $all_prefixes = array_map('strtolower', $all_prefixes);  
70 -  
71 - $keywords = Keyword::select(['id', 'title', 'seo_title'])->get();  
72 - foreach ($keywords as $item) {  
73 - $this_fix_keyword = $fix_keyword;  
74 - if (empty($item->title))  
75 - continue; 84 + $notify_master = false;
  85 + if (ProjectServer::useProject($project_id)) {
76 86
77 - $this->output('keyword id:' . $item->id . ' | title: ' . $item->title . ' | old seo title: ' . $item->seo_title); 87 + // 客户前缀
  88 + $tdk_class = new UpdateSeoTdk();
  89 + $info = $tdk_class->getDeployOptimize($project_id);
  90 + $fix_keyword = explode(",", $info['keyword_prefix']);
  91 + $fix_keyword = array_filter($fix_keyword);
78 92
79 - // 没有 SEO Title 直接生成  
80 - if (empty($item->seo_title)) {  
81 - $prefix = $tdk_class->getPrefixKeyword($project_id, 'prefix', 2, $item->title);  
82 - $suffix = $tdk_class->getPrefixKeyword($project_id, 'suffix', 2, trim($prefix . ' ' . $item->title));  
83 - if(Str::startsWith($suffix, ', ')){  
84 - $seo_title = $prefix . ' ' . $item->title . $suffix;  
85 - }else{  
86 - $seo_title = $prefix . ' ' . $item->title . ' ' . $suffix;  
87 - }  
88 -// $item->seo_title = trim($seo_title);  
89 -// $item->save();  
90 - $this->output('new seo title: ' . $seo_title);  
91 - continue;  
92 - } 93 + // 所有前缀
  94 + $all_prefixes = $tdk_class->getAllPrefix(1, $project_id);
  95 + $all_prefixes = array_map('strtolower', $all_prefixes);
93 96
94 - // 有 SEO Title 需要分析前后缀  
95 - $start = strpos($item->seo_title, $item->title); 97 + $keywords = Keyword::select(['id', 'title', 'seo_title', 'route'])->get();
  98 + foreach ($keywords as $item) {
  99 + $this_fix_keyword = $fix_keyword;
  100 + if (empty($item->title))
  101 + continue;
96 102
97 - // Title 和 SEO Title 不存在包含关系  
98 - if ($start === FALSE) {  
99 - $this->output('Title 和 SEO Title 不存在包含关系');  
100 - continue;  
101 - } 103 + $this->output('keyword id:' . $item->id . ' | title: ' . $item->title . ' | old seo title: ' . $item->seo_title);
102 104
103 - $prefix = $start == 0 ? '' : trim(substr($item->seo_title, 0, $start));  
104 - $prefix_array = explode(' ', $prefix);  
105 - $prefix_array = array_filter($prefix_array);  
106 - $need_num = 2 - count($prefix_array);  
107 - // 已经有两个前缀, 不在处理  
108 - if ($need_num <= 0) {  
109 - $this->output('已经有两个前缀, 不在处理');  
110 - continue;  
111 - } 105 + // 没有 SEO Title 直接生成
  106 + if (empty($item->seo_title)) {
  107 + $prefix = $tdk_class->getPrefixKeyword($project_id, 'prefix', 2, $item->title);
  108 + $suffix = $tdk_class->getPrefixKeyword($project_id, 'suffix', 2, trim($prefix . ' ' . $item->title));
  109 + if (Str::startsWith($suffix, ', ')) {
  110 + $seo_title = $prefix . ' ' . $item->title . $suffix;
  111 + } else {
  112 + $seo_title = $prefix . ' ' . $item->title . ' ' . $suffix;
  113 + }
  114 + $item->seo_title = trim($seo_title);
  115 + $item->save();
112 116
113 - // 关键词最后一个词是前缀的词,前后缀都不拼  
114 - $title_words = explode(' ', strtolower($item->title)); 117 + //存入按需更新表
  118 + UpdateNotify::addUpdateItem($project_id, 'product_keyword', $item->route);
  119 + $notify_master = true;
115 120
116 - // 关键词最后一个词是前缀的词,前后缀都不拼  
117 - if(in_array(Arr::last($title_words), $all_prefixes)) {  
118 - $this->output('关键词最后一个词是前缀的词, 前后缀都不拼');  
119 - continue;  
120 - } 121 + $this->output('new seo title: ' . $seo_title);
  122 + continue;
  123 + }
121 124
122 - // in,for,with,to,near,from 这些介词 只拼前缀,不拼后缀  
123 - $ban = []; 125 + // 有 SEO Title 需要分析前后缀
  126 + $start = strpos($item->seo_title, $item->title);
124 127
125 - // 关键词本身包含了前缀,也可以再拼一个不重复的前缀, 包含两个前缀就不拼前缀了  
126 - foreach ($title_words as $title_word) {  
127 - if(in_array($title_word, $all_prefixes)){  
128 - $ban[] = $title_word; 128 + // Title 和 SEO Title 不存在包含关系
  129 + if ($start === FALSE) {
  130 + $this->output('Title 和 SEO Title 不存在包含关系');
  131 + continue;
129 } 132 }
130 - }  
131 - $need_num = $need_num - count($ban);  
132 133
133 - // 关键词本身包含前缀,包含关键词大于等于需要的前缀,当前关键词不需要处理  
134 - if ($need_num <= 0) {  
135 - $this->output('关键词本身包含前缀,包含关键词大于等于需要的前缀,当前关键词不需要处理');  
136 - continue;  
137 - } 134 + $prefix = $start == 0 ? '' : trim(substr($item->seo_title, 0, $start));
  135 + $prefix_array = explode(' ', $prefix);
  136 + $prefix_array = array_filter($prefix_array);
  137 + $need_num = 2 - count($prefix_array);
  138 + // 已经有两个前缀, 不在处理
  139 + if ($need_num <= 0) {
  140 + $this->output('已经有两个前缀, 不在处理');
  141 + continue;
  142 + }
138 143
  144 + // 关键词最后一个词是前缀的词,前后缀都不拼
  145 + $title_words = explode(' ', strtolower($item->title));
139 146
140 - // services/service 结尾的词,后缀不拼manufacturer,factory  
141 - // manufacturer,factory 结尾的词,后缀不拼 services/service  
142 - // 有wholesale或cheap的词,后缀不拼 manufacturer,factory,exporter,company 147 + // 关键词最后一个词是前缀的词,前后缀都不拼
  148 + if (in_array(Arr::last($title_words), $all_prefixes)) {
  149 + $this->output('关键词最后一个词是前缀的词, 前后缀都不拼');
  150 + continue;
  151 + }
143 152
144 - // 关键词以manufacturer,factory,exporter,company结尾, 前缀不拼wholesale或cheap的词  
145 - if (Str::endsWith(strtolower($item->title), ['manufacturer', 'manufacturers', 'factory', 'factories', 'exporter', 'exporters', 'company', 'companies', 'supplier', 'suppliers']))  
146 - $ban = array_merge($ban, ['wholesale', 'cheap', 'buy']); 153 + // in,for,with,to,near,from 这些介词 只拼前缀,不拼后缀
  154 + $ban = [];
147 155
  156 + // 关键词本身包含了前缀,也可以再拼一个不重复的前缀, 包含两个前缀就不拼前缀了
  157 + foreach ($title_words as $title_word) {
  158 + if (in_array($title_word, $all_prefixes)) {
  159 + $ban[] = $title_word;
  160 + }
  161 + }
  162 + $need_num = $need_num - count($ban);
148 163
149 - foreach ($this_fix_keyword as $k => $keyword) {  
150 - // 被禁用的关键词  
151 - if (in_array(strtolower(Str::plural($keyword)), $ban)) {  
152 - unset($this_fix_keyword[$k]); 164 + // 关键词本身包含前缀,包含关键词大于等于需要的前缀,当前关键词不需要处理
  165 + if ($need_num <= 0) {
  166 + $this->output('关键词本身包含前缀,包含关键词大于等于需要的前缀,当前关键词不需要处理');
  167 + continue;
153 } 168 }
154 - if (in_array(strtolower(Str::singular($keyword)), $ban)) {  
155 - unset($this_fix_keyword[$k]); 169 +
  170 +
  171 + // services/service 结尾的词,后缀不拼manufacturer,factory
  172 + // manufacturer,factory 结尾的词,后缀不拼 services/service
  173 + // 有wholesale或cheap的词,后缀不拼 manufacturer,factory,exporter,company
  174 +
  175 + // 关键词以manufacturer,factory,exporter,company结尾, 前缀不拼wholesale或cheap的词
  176 + if (Str::endsWith(strtolower($item->title), ['manufacturer', 'manufacturers', 'factory', 'factories', 'exporter', 'exporters', 'company', 'companies', 'supplier', 'suppliers']))
  177 + $ban = array_merge($ban, ['wholesale', 'cheap', 'buy']);
  178 +
  179 +
  180 + foreach ($this_fix_keyword as $k => $keyword) {
  181 + // 被禁用的关键词
  182 + if (in_array(strtolower(Str::plural($keyword)), $ban)) {
  183 + unset($this_fix_keyword[$k]);
  184 + }
  185 + if (in_array(strtolower(Str::singular($keyword)), $ban)) {
  186 + unset($this_fix_keyword[$k]);
  187 + }
156 } 188 }
157 - }  
158 - $this_fix_keyword = array_diff($this_fix_keyword, $prefix_array);  
159 - shuffle($this_fix_keyword);  
160 - $need_keyword = [];  
161 - foreach ($this_fix_keyword as $v) {  
162 - if ($need_num == 0)  
163 - break;  
164 -  
165 - $is_repeat = false;  
166 - foreach ($need_keyword as $keyword) {  
167 - if (Str::singular($keyword) == Str::singular($v)) {  
168 - $is_repeat = true; 189 + $this_fix_keyword = array_diff($this_fix_keyword, $prefix_array);
  190 + shuffle($this_fix_keyword);
  191 + $need_keyword = [];
  192 + foreach ($this_fix_keyword as $v) {
  193 + if ($need_num == 0)
169 break; 194 break;
  195 +
  196 + $is_repeat = false;
  197 + foreach ($need_keyword as $keyword) {
  198 + if (Str::singular($keyword) == Str::singular($v)) {
  199 + $is_repeat = true;
  200 + break;
  201 + }
170 } 202 }
  203 + if ($is_repeat)
  204 + continue;
  205 +
  206 + $need_keyword[] = $v;
  207 + $need_num--;
171 } 208 }
172 - if ($is_repeat)  
173 - continue; 209 + $item->seo_title = trim(implode(' ', $need_keyword) . ' ' . trim($item->seo_title));
  210 + $item->save();
174 211
175 - $need_keyword[] = $v;  
176 - $need_num--; 212 + //存入按需更新表
  213 + UpdateNotify::addUpdateItem($project_id, 'product_keyword', $item->route);
  214 + $notify_master = true;
  215 +
  216 + $this->output('new seo title: ' . implode(' ', $need_keyword) . ' ' . trim($item->seo_title));
177 } 217 }
178 -// $item->seo_title = trim(implode(' ', $need_keyword) . ' ' . trim($item->seo_title));  
179 -// $item->save();  
180 - $this->output('new seo title: ' . implode(' ', $need_keyword) . ' ' . trim($item->seo_title));  
181 } 218 }
  219 +
  220 + if ($notify_master) {
  221 + //通知主站按需更新
  222 + $this->sendNotify($project_id, 2);
  223 + }
  224 +
182 return true; 225 return true;
183 } 226 }
184 227
@@ -188,8 +231,40 @@ class SplicePrefix extends Command @@ -188,8 +231,40 @@ class SplicePrefix extends Command
188 */ 231 */
189 public function getProject() 232 public function getProject()
190 { 233 {
191 - $project_ids = Project::where(['type' => Project::TYPE_TWO, 'project_type' => Project::TYPE_ZERO, 'delete_status' => Project::IS_DEL_FALSE, 'is_remain_today' => 0])->pluck('id')->toArray();  
192 - return $project_ids; 234 + return Project::where(['type' => Project::TYPE_TWO, 'project_type' => Project::TYPE_ZERO, 'delete_status' => Project::IS_DEL_FALSE, 'is_remain_today' => 0])->pluck('id')->toArray();
  235 + }
  236 +
  237 + /**
  238 + * 页面更新
  239 + * @param $project_id
  240 + * @param $route
  241 + * @author Akun
  242 + * @date 2025/10/30 14:33
  243 + */
  244 + public function sendNotify($project_id, $route)
  245 + {
  246 + //获取当前项目的域名
  247 + $domainModel = new DomainInfo();
  248 + $domainInfo = $domainModel->read(['project_id' => $project_id]);
  249 + if ($domainInfo === false) {
  250 + //获取测试域名
  251 + $deployBuildModel = new DeployBuild();
  252 + $buildInfo = $deployBuildModel->read(['project_id' => $project_id]);
  253 + $domain = $buildInfo['test_domain'];
  254 + } else {
  255 + $domain = 'https://' . $domainInfo['domain'] . '/';
  256 + }
  257 + $url = $domain . 'api/update_page/';
  258 + $param = [
  259 + 'project_id' => $project_id,
  260 + 'type' => 1,
  261 + 'route' => $route,
  262 + 'url' => [],
  263 + 'language' => [],
  264 + ];
  265 + NoticeLog::createLog(NoticeLog::GENERATE_PAGE, ['c_url' => $url, 'c_params' => $param], date('Y-m-d H:i:s', time() + 300));
  266 +
  267 + $this->output('更新中请稍后, 更新完成将会发送站内信通知更新结果!');
193 } 268 }
194 269
195 /** 270 /**
@@ -326,16 +326,6 @@ class ProjectUpdate extends Command @@ -326,16 +326,6 @@ class ProjectUpdate extends Command
326 //分类 326 //分类
327 $category_id = ''; 327 $category_id = '';
328 $category_arr = []; 328 $category_arr = [];
329 - if ($project_id == 596 && empty($item['category'])) {  
330 - //596项目,产品没有分类,默认属于Featured分类  
331 - $item['category'] = [  
332 - [  
333 - 'id' => 623,  
334 - 'name' => 'Featured',  
335 - 'pid' => 0  
336 - ]  
337 - ];  
338 - }  
339 if ($item['category'] ?? []) { 329 if ($item['category'] ?? []) {
340 if ($project_id == 4075 && count($item['category']) == 1 && $item['category'][0]['name'] == 'Featured') { 330 if ($project_id == 4075 && count($item['category']) == 1 && $item['category'][0]['name'] == 'Featured') {
341 //4075项目特殊处理:不采集Featured分类下的产品 331 //4075项目特殊处理:不采集Featured分类下的产品
@@ -39,6 +39,11 @@ class GeoWritingTaskController extends BaseController @@ -39,6 +39,11 @@ class GeoWritingTaskController extends BaseController
39 * @time :2025/10/25 15:12 39 * @time :2025/10/25 15:12
40 */ 40 */
41 public function lists(){ 41 public function lists(){
  42 + $this->request->validate([
  43 + 'project_id'=>'required',
  44 + ],[
  45 + 'project_id.required' => 'project_id不能为空',
  46 + ]);
42 $data = $this->logic->listWritingTask($this->map,$this->page,$this->row,$this->order); 47 $data = $this->logic->listWritingTask($this->map,$this->page,$this->row,$this->order);
43 $this->response('success',Code::SUCCESS,$data); 48 $this->response('success',Code::SUCCESS,$data);
44 } 49 }
@@ -39,6 +39,11 @@ class GeoWritingsController extends BaseController @@ -39,6 +39,11 @@ class GeoWritingsController extends BaseController
39 * @time :2025/10/25 15:53 39 * @time :2025/10/25 15:53
40 */ 40 */
41 public function lists(){ 41 public function lists(){
  42 + $this->request->validate([
  43 + 'project_id'=>'required',
  44 + ],[
  45 + 'project_id.required' => 'project_id不能为空',
  46 + ]);
42 $data = $this->logic->listWriting($this->map,$this->page,$this->row,$this->order); 47 $data = $this->logic->listWriting($this->map,$this->page,$this->row,$this->order);
43 $this->response('success',Code::SUCCESS,$data); 48 $this->response('success',Code::SUCCESS,$data);
44 } 49 }
@@ -251,7 +251,6 @@ class InquiryController extends BaseController @@ -251,7 +251,6 @@ class InquiryController extends BaseController
251 $data = $data['list'] ?? []; 251 $data = $data['list'] ?? [];
252 foreach ($data as &$item){ 252 foreach ($data as &$item){
253 //非正常登录的 253 //非正常登录的
254 -  
255 if(($this->user['login_source']??0) != 2 && ($this->user['login_source']??0) != 3){ 254 if(($this->user['login_source']??0) != 2 && ($this->user['login_source']??0) != 3){
256 if(!empty($item['email']) && (strpos($item['email'], '@') !== false)){ 255 if(!empty($item['email']) && (strpos($item['email'], '@') !== false)){
257 $item['email'] = email_desensitize($item['email']); 256 $item['email'] = email_desensitize($item['email']);
@@ -259,9 +258,7 @@ class InquiryController extends BaseController @@ -259,9 +258,7 @@ class InquiryController extends BaseController
259 //脱敏 258 //脱敏
260 !empty($item['phone']) && $item['phone'] = substr($item['phone'], 0, -4) . '****'; 259 !empty($item['phone']) && $item['phone'] = substr($item['phone'], 0, -4) . '****';
261 } 260 }
262 -  
263 $item['ip_address'] = "{$item['country']}({$item['ip']})"; 261 $item['ip_address'] = "{$item['country']}({$item['ip']})";
264 -  
265 if(!empty($this->param['form_id'])){ 262 if(!empty($this->param['form_id'])){
266 $item = array_merge($item, $item['data']); 263 $item = array_merge($item, $item['data']);
267 } 264 }
@@ -69,9 +69,11 @@ class GeoConfirmLogic extends BaseLogic @@ -69,9 +69,11 @@ class GeoConfirmLogic extends BaseLogic
69 { 69 {
70 $data = $this->model->read($this->param); 70 $data = $this->model->read($this->param);
71 if($data === false){ 71 if($data === false){
72 - $this->fail('当前数据不存在或者已被删除'); 72 + return $this->success();
  73 + }
  74 + if(empty($data['confirm'])){
  75 + $data['confirm'] = $data['content'];
73 } 76 }
74 - $data['confirm'] = $data['content'];  
75 return $this->success($data); 77 return $this->success($data);
76 } 78 }
77 79
@@ -112,6 +112,9 @@ class GeoLogic extends BaseLogic @@ -112,6 +112,9 @@ class GeoLogic extends BaseLogic
112 { 112 {
113 //获取问题数量 113 //获取问题数量
114 $geo_question_count = GeoQuestion::selectRaw('SUM(JSON_LENGTH(question)) as total_count')->where('project_id',$this->param['project_id'])->value('total_count'); 114 $geo_question_count = GeoQuestion::selectRaw('SUM(JSON_LENGTH(question)) as total_count')->where('project_id',$this->param['project_id'])->value('total_count');
  115 + if(empty($geo_question_count)){
  116 + $geo_question_count = 0;
  117 + }
115 $geo_pr_count = GeoLink::where('project_id',$this->param['project_id'])->count(); 118 $geo_pr_count = GeoLink::where('project_id',$this->param['project_id'])->count();
116 $geo_writings_count = GeoWritings::where('project_id',$this->param['project_id'])->count(); 119 $geo_writings_count = GeoWritings::where('project_id',$this->param['project_id'])->count();
117 return $this->success(['geo_writings_count'=>$geo_writings_count,'geo_pr_count'=>$geo_pr_count,'geo_question_count'=>$geo_question_count]); 120 return $this->success(['geo_writings_count'=>$geo_writings_count,'geo_pr_count'=>$geo_pr_count,'geo_question_count'=>$geo_question_count]);
@@ -111,9 +111,19 @@ class DomainSettingLogic extends BaseLogic @@ -111,9 +111,19 @@ class DomainSettingLogic extends BaseLogic
111 if (count($domain_array) == 1) { 111 if (count($domain_array) == 1) {
112 $this->fail('请填写正确的主域名'); 112 $this->fail('请填写正确的主域名');
113 } elseif (count($domain_array) == 2) { 113 } elseif (count($domain_array) == 2) {
114 - array_unshift($domain_array, 'blog'); 114 + if ($this->user['project_id'] == 5113) {
  115 + //5113项目二级域名使用news
  116 + array_unshift($domain_array, 'news');
  117 + } else {
  118 + array_unshift($domain_array, 'blog');
  119 + }
115 } else { 120 } else {
116 - $domain_array[0] = 'blog'; 121 + if ($this->user['project_id'] == 5113) {
  122 + //5113项目二级域名使用news
  123 + $domain_array[0] = 'news';
  124 + } else {
  125 + $domain_array[0] = 'blog';
  126 + }
117 } 127 }
118 $blog_domain = implode('.', $domain_array); 128 $blog_domain = implode('.', $domain_array);
119 129
@@ -145,7 +155,7 @@ class DomainSettingLogic extends BaseLogic @@ -145,7 +155,7 @@ class DomainSettingLogic extends BaseLogic
145 155
146 //变更ip使用数量 156 //变更ip使用数量
147 $server_ip_model->edit(['total' => $record_info['total'] + 1], ['id' => $record_info['id']]); 157 $server_ip_model->edit(['total' => $record_info['total'] + 1], ['id' => $record_info['id']]);
148 - $server_model->where(['id'=>$record_info['servers_id']])->increment('being_number',1); 158 + $server_model->where(['id' => $record_info['servers_id']])->increment('being_number', 1);
149 159
150 //创建建站任务 160 //创建建站任务
151 $domain_create_model = new DomainCreateTask(); 161 $domain_create_model = new DomainCreateTask();
@@ -204,7 +214,7 @@ class DomainSettingLogic extends BaseLogic @@ -204,7 +214,7 @@ class DomainSettingLogic extends BaseLogic
204 214
205 //变更ip使用数量 215 //变更ip使用数量
206 $server_ip_model->edit(['total' => $record_info['total'] + 1], ['id' => $record_info['id']]); 216 $server_ip_model->edit(['total' => $record_info['total'] + 1], ['id' => $record_info['id']]);
207 - $server_model->where(['id'=>$record_info['servers_id']])->increment('being_number',1); 217 + $server_model->where(['id' => $record_info['servers_id']])->increment('being_number', 1);
208 } 218 }
209 219
210 DB::commit(); 220 DB::commit();
@@ -8,6 +8,8 @@ @@ -8,6 +8,8 @@
8 namespace App\Models\Geo; 8 namespace App\Models\Geo;
9 9
10 use App\Models\Base; 10 use App\Models\Base;
  11 +use App\Models\Project\DeployBuild;
  12 +use App\Models\Project\Project;
11 use App\Models\Workchat\MessagePush; 13 use App\Models\Workchat\MessagePush;
12 14
13 /** 15 /**
@@ -42,8 +44,23 @@ class GeoConfirm extends Base @@ -42,8 +44,23 @@ class GeoConfirm extends Base
42 public static function typeMapping() 44 public static function typeMapping()
43 { 45 {
44 return [ 46 return [
45 - self::TYPE_TITLE => '确认标题',  
46 - self::TYPE_KEYWORD => '确认关键词' 47 + self::TYPE_TITLE => '核心关键词问题已整理,请查看并确认',
  48 + self::TYPE_KEYWORD => '文章标题已整理,请查看并确认'
  49 + ];
  50 + }
  51 +
  52 + /**
  53 + * @remark :确认返回数据
  54 + * @name :typeDesc
  55 + * @author :lyh
  56 + * @method :post
  57 + * @time :2025/10/31 10:10
  58 + */
  59 + public static function typeDesc()
  60 + {
  61 + return [
  62 + self::TYPE_TITLE => '需选择确认10个文章标题,后续根据您确认的文章标题整理文章内容;如有补充展会、资质证书等资料,可一并提供。',
  63 + self::TYPE_KEYWORD => '需选择确认10个核心关键词问题,后续根据您确认的核心关键词问题整理文章标题;建议提供展会、资质证书等资料。'
47 ]; 64 ];
48 } 65 }
49 66
@@ -98,9 +115,14 @@ class GeoConfirm extends Base @@ -98,9 +115,14 @@ class GeoConfirm extends Base
98 $type = MessagePush::TYPE_GEO_CONFIRM; 115 $type = MessagePush::TYPE_GEO_CONFIRM;
99 $token = uniqid().$friend_id; 116 $token = uniqid().$friend_id;
100 $created_at = $updated_at = now(); 117 $created_at = $updated_at = now();
  118 + $projectModel = new Project();
  119 + $company = $projectModel->getValue(['id'=>$project_id],'company');
  120 + $deployModel = new DeployBuild();
  121 + $seo_plan = $deployModel->getValue(['project_id'=>$project_id],'seo_plan');
  122 + $seo_plan_name = ($projectModel::seoMap()[$seo_plan]) ?? '无选择';
101 $content_array = [ 123 $content_array = [
102 - 'title' => self::typeMapping()[$data->type],  
103 - 'desc' => self::typeMapping()[$data->type], 124 + 'title' => "【{$company} {$seo_plan_name}】".self::typeMapping()[$data->type],
  125 + 'desc' => self::typeDesc()[$data->type],
104 'size' => 0, 126 'size' => 0,
105 'thumbSize' => 0, 127 'thumbSize' => 0,
106 'thumbUrl' => 'https://hub.globalso.com/logocm.png', 128 'thumbUrl' => 'https://hub.globalso.com/logocm.png',
@@ -8,6 +8,8 @@ @@ -8,6 +8,8 @@
8 namespace App\Models\Geo; 8 namespace App\Models\Geo;
9 9
10 use App\Models\Base; 10 use App\Models\Base;
  11 +use App\Models\Project\DeployBuild;
  12 +use App\Models\Project\Project;
11 use App\Models\ProjectAssociation\ProjectAssociation; 13 use App\Models\ProjectAssociation\ProjectAssociation;
12 use App\Models\Workchat\MessagePush; 14 use App\Models\Workchat\MessagePush;
13 use Illuminate\Support\Facades\Crypt; 15 use Illuminate\Support\Facades\Crypt;
@@ -90,10 +92,15 @@ class GeoWritings extends Base @@ -90,10 +92,15 @@ class GeoWritings extends Base
90 'project_id' => $project_id, 92 'project_id' => $project_id,
91 'send_at' => time() 93 'send_at' => time()
92 ]; 94 ];
  95 + $projectModel = new Project();
  96 + $company = $projectModel->getValue(['id'=>$project_id],'company');
  97 + $deployModel = new DeployBuild();
  98 + $seo_plan = $deployModel->getValue(['project_id'=>$project_id],'seo_plan');
  99 + $seo_plan_name = ($projectModel::seoMap()[$seo_plan]) ?? '无选择';
93 $token = Crypt::encrypt($param); 100 $token = Crypt::encrypt($param);
94 $content_array = [ 101 $content_array = [
95 - 'title' => "确认核心文章",  
96 - 'desc' => '确认核心文章', 102 + 'title' => "【{$company} {$seo_plan_name}】核心文章已整理,请查看并确认",
  103 + 'desc' => '需选择确认10篇文章,后续根据您确认的文章进行外链发布。',
97 'size' => 0, 104 'size' => 0,
98 'thumbSize' => 0, 105 'thumbSize' => 0,
99 'thumbUrl' => 'https://hub.globalso.com/logocm.png', 106 'thumbUrl' => 'https://hub.globalso.com/logocm.png',