作者 lyh

gx

@@ -97,6 +97,7 @@ class ProjectImport extends Command @@ -97,6 +97,7 @@ class ProjectImport extends Command
97 $success_count = 0; //成功导入条数 97 $success_count = 0; //成功导入条数
98 $repeat_count = 0; //过滤已存在条数 98 $repeat_count = 0; //过滤已存在条数
99 $fail_count = 0; 99 $fail_count = 0;
  100 + $fail_line = [];
100 if (count($line_of_text) > 1) { 101 if (count($line_of_text) > 1) {
101 102
102 //设置数据库 103 //设置数据库
@@ -134,6 +135,7 @@ class ProjectImport extends Command @@ -134,6 +135,7 @@ class ProjectImport extends Command
134 } 135 }
135 } catch (\Exception $e) { 136 } catch (\Exception $e) {
136 $fail_count += 1; 137 $fail_count += 1;
  138 + $fail_line[] = $k + 1;
137 echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', title: ' . $v[0] . ', import fail, error: ' . $e->getMessage() . PHP_EOL; 139 echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', title: ' . $v[0] . ', import fail, error: ' . $e->getMessage() . PHP_EOL;
138 } 140 }
139 } 141 }
@@ -148,7 +150,7 @@ class ProjectImport extends Command @@ -148,7 +150,7 @@ class ProjectImport extends Command
148 $task->success_count += $success_count; 150 $task->success_count += $success_count;
149 $task->save(); 151 $task->save();
150 152
151 - $this->send_mail($task->user_id, $task->created_at, $task->type, $success_count, $fail_count, $repeat_count, ''); 153 + $this->send_mail($task->user_id, $task->created_at, $task->type, $success_count, $fail_count, $repeat_count, '', $fail_line);
152 154
153 echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', import end, total count: ' . $total_count . ', success count: ' . $success_count . PHP_EOL; 155 echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', import end, total count: ' . $total_count . ', success count: ' . $success_count . PHP_EOL;
154 156
@@ -192,7 +194,7 @@ class ProjectImport extends Command @@ -192,7 +194,7 @@ class ProjectImport extends Command
192 } 194 }
193 195
194 //发送站内通知 196 //发送站内通知
195 - protected function send_mail($user_list, $time, $type, $success_count, $repeat_count, $fail_count, $reason) 197 + protected function send_mail($user_list, $time, $type, $success_count, $repeat_count, $fail_count, $reason, $fail_line = [])
196 { 198 {
197 if ($type == ImportTask::TYPE_NEWS) { 199 if ($type == ImportTask::TYPE_NEWS) {
198 $type_content = '新闻'; 200 $type_content = '新闻';
@@ -206,6 +208,7 @@ class ProjectImport extends Command @@ -206,6 +208,7 @@ class ProjectImport extends Command
206 $repeat_count && $content .= ',过滤已存在数据:' . $repeat_count . ' 条'; 208 $repeat_count && $content .= ',过滤已存在数据:' . $repeat_count . ' 条';
207 $fail_count && $content .= ',导入失败:' . $fail_count . ' 条'; 209 $fail_count && $content .= ',导入失败:' . $fail_count . ' 条';
208 $reason && $content .= ',原因:' . $reason; 210 $reason && $content .= ',原因:' . $reason;
  211 + $fail_line && $content .= ',失败行数:' . implode(',', $fail_line);
209 212
210 $mail_model = new Mail(); 213 $mail_model = new Mail();
211 $mail_model->add([ 214 $mail_model->add([
@@ -2,7 +2,10 @@ @@ -2,7 +2,10 @@
2 2
3 namespace App\Console\Commands; 3 namespace App\Console\Commands;
4 4
  5 +use App\Helper\Arr;
5 use App\Helper\Common; 6 use App\Helper\Common;
  7 +use App\Helper\Gpt;
  8 +use App\Helper\Translate;
6 use App\Models\Ai\AiCommand; 9 use App\Models\Ai\AiCommand;
7 use App\Models\Mail\Mail; 10 use App\Models\Mail\Mail;
8 use App\Models\Project\DeployOptimize; 11 use App\Models\Project\DeployOptimize;
@@ -33,7 +36,7 @@ class UpdateSeoTdk extends Command @@ -33,7 +36,7 @@ class UpdateSeoTdk extends Command
33 * 36 *
34 * @var string 37 * @var string
35 */ 38 */
36 - protected $description = '一键生成sdk'; 39 + protected $description = '一键生成tdk';
37 40
38 /** 41 /**
39 * Create a new command instance. 42 * Create a new command instance.
@@ -46,17 +49,95 @@ class UpdateSeoTdk extends Command @@ -46,17 +49,95 @@ class UpdateSeoTdk extends Command
46 } 49 }
47 50
48 /** 51 /**
  52 + * '表' => [
  53 + * '指令key' => '表字段'
  54 + * ]
  55 + * @return array
  56 + * @author zbj
  57 + * @date 2023/11/3
  58 + */
  59 + protected $maps = [
  60 + 'gl_web_custom_template' => [
  61 + 'page_title' => 'title',
  62 + 'page_meta_keywords' => 'keywords',
  63 + 'page_meta_description' => 'description',
  64 + ],
  65 + 'gl_product' => [
  66 + 'product_title' => 'seo_mate.title',
  67 + 'product_meta_keywords' => 'seo_mate.keyword',
  68 + 'product_meta_description' => 'seo_mate.description',
  69 + ],
  70 + 'gl_product_category' => [
  71 + 'product_cat_title' => 'seo_title',
  72 + 'product_cat_meta_keywords' => 'seo_keywords',
  73 + 'product_cat_meta_description' => 'seo_des',
  74 + ],
  75 + 'gl_blog' => [
  76 + 'blog_title' => 'seo_title',
  77 + 'blog_meta_keywords' => 'seo_keywords',
  78 + 'blog_meta_description' => 'seo_description',
  79 + ],
  80 + 'gl_blog_category' => [
  81 + 'blog_cat_title' => 'seo_title',
  82 + 'blog_cat_meta_keywords' => 'seo_keywords',
  83 + 'blog_cat_meta_description' => 'seo_des',
  84 + ],
  85 + 'gl_news' => [
  86 + 'news_title' => 'seo_title',
  87 + 'news_meta_keywords' => 'seo_keywords',
  88 + 'news_meta_description' => 'seo_description',
  89 + ],
  90 + 'gl_news_category' => [
  91 + 'news_cat_title' => 'seo_title',
  92 + 'news_cat_meta_keywords' => 'seo_keywords',
  93 + 'news_cat_meta_description' => 'seo_des',
  94 + ],
  95 + 'gl_product_keyword' => [
  96 + 'tags_title' => 'seo_title',
  97 + 'tags_meta_keywords' => 'seo_keywords',
  98 + 'tags_meta_description' => 'seo_description',
  99 + 'tags_content_title' => 'keyword_title',
  100 + 'tags_content_description' => 'keyword_content',
  101 + ]
  102 + ];
  103 +
  104 + /**
  105 + * topic-对相应字段
  106 + * @var array
  107 + */
  108 + protected $topic_fields = [
  109 + 'gl_web_custom_template' => 'name',
  110 + 'gl_product' => 'title',
  111 + 'gl_product_category' => 'title',
  112 + 'gl_blog' => 'name',
  113 + 'gl_blog_category' => 'name',
  114 + 'gl_news' => 'name',
  115 + 'gl_news_category' => 'name',
  116 + 'gl_product_keyword' => 'title'
  117 + ];
  118 +
  119 + /**
  120 + * 使用核心关键词的key 数量
  121 + * @var array
  122 + */
  123 + protected $core_keyword_keys = [
  124 + 'page_meta_keywords' => 1,
  125 + 'blog_cat_meta_keywords' => 8,
  126 + 'news_cat_meta_keywords' => 8,
  127 + ];
  128 +
  129 + /**
49 * @return bool 130 * @return bool
50 */ 131 */
51 public function handle() 132 public function handle()
52 { 133 {
53 - while (true){ 134 + while (true) {
54 $project_id = Redis::rpop('updateSeoTdk'); 135 $project_id = Redis::rpop('updateSeoTdk');
55 - if(!$project_id){ 136 + if (!$project_id) {
56 sleep(2); 137 sleep(2);
57 continue; 138 continue;
58 } 139 }
59 - echo date('Y-m-d H:i:s') . ' start: ' . $project_id . PHP_EOL; 140 + echo date('Y-m-d H:i:s') . ' start project_id: ' . $project_id . PHP_EOL;
60 try { 141 try {
61 ProjectServer::useProject($project_id); 142 ProjectServer::useProject($project_id);
62 $this->updateProduct($project_id); 143 $this->updateProduct($project_id);
@@ -75,291 +156,113 @@ class UpdateSeoTdk extends Command @@ -75,291 +156,113 @@ class UpdateSeoTdk extends Command
75 echo date('Y-m-d H:i:s') . ' end: ' . $project_id . PHP_EOL; 156 echo date('Y-m-d H:i:s') . ' end: ' . $project_id . PHP_EOL;
76 } 157 }
77 } 158 }
78 - /**  
79 - * @remark :更新产品tdk  
80 - * @name :updateProduct  
81 - * @author :lyh  
82 - * @method :post  
83 - * @time :2023/8/19 9:25  
84 - */  
85 - public function updateProduct($project_id){  
86 - echo date('Y-m-d H:i:s') . '更新产品--updateProduct: 项目id' . $project_id . PHP_EOL;  
87 - $list = DB::connection('custom_mysql')->table('gl_product')->where(['status'=>1,'project_id'=>$project_id])->get()->toArray();  
88 - if(!empty($list)){  
89 - foreach ($list as $v){  
90 - $v = (array)$v;  
91 - echo date('Y-m-d H:i:s') . ' updateProduct: ' . $v['id'] . PHP_EOL;  
92 - $seo_arr = json_decode($v['seo_mate'], true) ?: [];  
93 - //更新seo_title  
94 - if(!isset($seo_arr['title']) || empty($seo_arr['title'])){  
95 - //查看是否有指令  
96 - $aiCommandModel = new AiCommand();  
97 - $AiInfo = $aiCommandModel->read(['key'=>'product_seo_title'],['ai']);  
98 - if(!empty($AiInfo['ai'])){  
99 - $seo_arr['title'] = $this->ai_send('product_seo_title',$v['title']);  
100 - }else {  
101 - $seo_arr['title'] = $v['title'];  
102 - }  
103 - }  
104 - //更新seo_keyword  
105 - if(!isset($seo_arr['keyword']) || empty($seo_arr['keyword'])){  
106 - $seo_arr['keyword'] = $this->ai_send('seo_keywords',$v['title']);  
107 - }  
108 - //更新seo_keyword  
109 - if(!isset($seo_arr['description']) || empty($seo_arr['description'])){  
110 - $seo_arr['description'] = $this->ai_send('seo_meta_description',$v['title']);  
111 - }  
112 - $ser_str = json_encode($seo_arr,true);  
113 - DB::connection('custom_mysql')->table('gl_product')->where(['id'=>$v['id']])->update(['seo_mate'=>$ser_str]);  
114 - }  
115 159
116 - }  
117 - return true;  
118 - } 160 + public function seo_tdk($project_id)
  161 + {
  162 + $ai_commands = AiCommand::select('key', 'scene', 'ai')->get()->toArray();
  163 + $ai_commands = Arr::setValueToKey($ai_commands, 'key');
119 164
120 - /**  
121 - * @remark :更新产品tdk  
122 - * @name :updateProduct  
123 - * @author :lyh  
124 - * @method :post  
125 - * @time :2023/8/19 9:25  
126 - */  
127 - public function updateProductCate($project_id){  
128 - echo date('Y-m-d H:i:s') . '更新产品分类--updateProductCate: 项目id' . $project_id . PHP_EOL;  
129 - $list = DB::connection('custom_mysql')->table('gl_product_category')->where(['status'=>1,'project_id'=>$project_id])->get()->toArray();  
130 - if(!empty($list)){  
131 - foreach ($list as $v){  
132 - $v = (array)$v;  
133 - echo date('Y-m-d H:i:s') . ' updateProductCate: ' . $v['id'] . PHP_EOL;  
134 - $data = [];  
135 - if(empty($v['seo_title'])){  
136 - $aiCommandModel = new AiCommand();  
137 - $AiInfo = $aiCommandModel->read(['key'=>'product_cate_seo_title'],['ai']);  
138 - if(!empty($AiInfo['ai'])){  
139 - $data['seo_title'] = $this->ai_send('product_cate_seo_title',$v['title']);  
140 - }else{  
141 - $data['seo_title'] = $v['title'];  
142 - }  
143 - }  
144 - if(empty($v['seo_keywords'])){  
145 - $data['seo_keywords'] = $this->ai_send('seo_keywords',$v['title']);  
146 - }  
147 - if(empty($v['seo_des'])){  
148 - $name = $this->companyName($project_id);  
149 - if(!empty($name)){  
150 - $data['seo_des'] = $this->ai_send('page_meta_description',$v['title'],$name);  
151 - }  
152 - }  
153 - if(!$data){  
154 - continue;  
155 - }  
156 - DB::connection('custom_mysql')->table('gl_product_category')->where(['id'=>$v['id']])->update($data);  
157 - }  
158 - }  
159 - return true;  
160 - } 165 + foreach ($this->maps as $table => $map) {
  166 + echo date('Y-m-d H:i:s') . '更新--' . $table . ': 项目id' . $project_id . PHP_EOL;
  167 + $list = DB::connection('custom_mysql')->table($table)->get()->toArray();
  168 + if (!empty($list)) {
  169 + foreach ($list as $v) {
  170 + $v = (array)$v;
  171 + echo date('Y-m-d H:i:s') . '更新--' . $table . ':id' . $v['id'] . PHP_EOL;
  172 + $data = [];
  173 + $json_field = '';
161 174
162 - /**  
163 - * @remark :更新新闻Tdk  
164 - * @name :updateNews  
165 - * @author :lyh  
166 - * @method :post  
167 - * @time :2023/8/19 10:06  
168 - */  
169 - public function updateNews($project_id){  
170 - echo date('Y-m-d H:i:s') . '更新新闻--updateNews: 项目id' . $project_id . PHP_EOL;  
171 - $list = DB::connection('custom_mysql')->table('gl_news')->where(['status'=>1,'project_id'=>$project_id])->get()->toArray();  
172 - if(!empty($list)){  
173 - foreach ($list as $k => $v){  
174 - $v = (array)$v;  
175 - echo date('Y-m-d H:i:s') . ' updateNews: ' . $v['id'] . PHP_EOL;  
176 - $data = [];  
177 - if(empty($v['seo_title'])){  
178 - $aiCommandModel = new AiCommand();  
179 - $AiInfo = $aiCommandModel->read(['key'=>'news_seo_title'],['ai']);  
180 - if(!empty($AiInfo['ai'])){  
181 - $data['seo_title'] = $this->ai_send('news_seo_title',$v['name']);  
182 - }else{  
183 - $data['seo_title'] = $v['name'];  
184 - }  
185 - }  
186 - if(empty($v['seo_keywords'])){  
187 - $data['seo_keywords'] = $this->ai_send('seo_keywords',$v['name']);  
188 - }  
189 - if(empty($v['seo_description'])){  
190 - $data['seo_description'] = $this->ai_send('seo_meta_description',$v['name']);  
191 - }  
192 - if(!$data){  
193 - continue;  
194 - }  
195 - DB::connection('custom_mysql')->table('gl_news')->where(['id'=>$v['id']])->update($data);  
196 - }  
197 - }  
198 - return true;  
199 - } 175 + foreach ($map as $ai_key => $field) {
  176 + $field_arr = explode('.', $field);
  177 + if (count($field_arr) > 1) {
  178 + $json_field = $field_arr[0];
  179 + $value = json_decode($v[$field_arr[0]], true)[$field_arr[1]] ?? '';
  180 + } else {
  181 + $value = $v[$field] ?? '';
  182 + }
  183 + //已有值的 跳过
  184 + if ($value) {
  185 + echo $field.'已有值 跳过' . PHP_EOL;
  186 + continue;
  187 + }
  188 + //AI生成
  189 + if (!empty($ai_commands[$ai_key]['ai'])) {
  190 + $prompt = $this->getPrompt($project_id, $ai_commands[$ai_key]['ai'], $table, $v);
  191 + if(!$prompt){
  192 + continue;
  193 + }
200 194
201 - /**  
202 - * @remark :更新新闻Tdk  
203 - * @name :updateNews  
204 - * @author :lyh  
205 - * @method :post  
206 - * @time :2023/8/19 10:06  
207 - */  
208 - public function updateNewsCate($project_id){  
209 - echo date('Y-m-d H:i:s') . '更新新闻分类--updateNewsCate: 项目id' . $project_id . PHP_EOL;  
210 - $list = DB::connection('custom_mysql')->table('gl_news_category')->where(['status'=>0,'project_id'=>$project_id])->get()->toArray();  
211 - if(!empty($list)){  
212 - foreach ($list as $k => $v){  
213 - $v = (array)$v;  
214 - echo date('Y-m-d H:i:s') . ' updateNewsCate: ' . $v['id'] . PHP_EOL;  
215 - $data = [];  
216 - if(empty($v['seo_title'])){  
217 - $aiCommandModel = new AiCommand();  
218 - $AiInfo = $aiCommandModel->read(['key'=>'news_cate_seo_title'],['ai']);  
219 - if(!empty($AiInfo['ai'])){  
220 - $data['seo_title'] = $this->ai_send('news_cate_seo_title',$v['name']);  
221 - }else{  
222 - $data['seo_title'] = $v['name']; 195 + if (count($field_arr) > 1) {
  196 + $data[$field_arr[0]][$field_arr[1]] = $this->ai_send($prompt);
  197 + }else{
  198 + $data[$field] = $this->ai_send($prompt);
  199 + }
  200 + } else {
  201 + //直接使用topic
  202 + if (count($field_arr) > 1) {
  203 + $data[$field_arr[0]][$field_arr[1]] = $v[$this->topic_fields[$table]] ?? '';
  204 + //使用核心关键词
  205 + if(in_array($ai_key, array_keys($this->core_keyword_keys))){
  206 + $data[$field_arr[0]][$field_arr[1]] = $this->mainKeywords($project_id, $this->core_keyword_keys[$ai_key]);
  207 + }
  208 + }else{
  209 + $data[$field] = $v[$this->topic_fields[$table]] ?? '';
  210 + //使用核心关键词
  211 + if(in_array($ai_key, array_keys($this->core_keyword_keys))){
  212 + $data[$field] = $this->mainKeywords($project_id, $this->core_keyword_keys[$ai_key]);
  213 + }
  214 + }
  215 + }
223 } 216 }
224 - }  
225 - if(empty($v['seo_keywords'])){  
226 - //获取核心关键词  
227 - $main_keyword = $this->mainKeywords($project_id);  
228 - if(!empty($main_keyword)){  
229 - $data['seo_keywords'] = $this->ai_send('seo_keywords',$main_keyword); 217 + if(!$data){
  218 + continue;
230 } 219 }
231 - }  
232 - if(empty($v['seo_des'])){  
233 - $name = $this->companyName($project_id);  
234 - if(!empty($name)){  
235 - $data['seo_des'] = $this->ai_send('page_meta_description',$v['title'],$name); 220 + if($json_field){
  221 + $old_data = json_decode($v[$field_arr[0]], true);
  222 + foreach ($old_data as $kk=>$vv){
  223 + empty($data[$json_field][$kk]) && $data[$json_field][$kk] = $vv;
  224 + }
  225 + $data[$json_field] = json_encode($data[$json_field]);
236 } 226 }
  227 + DB::connection('custom_mysql')->table($table)->where(['id' => $v['id']])->update($data);
237 } 228 }
238 - if(!$data){  
239 - continue;  
240 - }  
241 - DB::connection('custom_mysql')->table('gl_news_category')->where(['id'=>$v['id']])->update($data);  
242 } 229 }
243 } 230 }
244 - return true;  
245 } 231 }
246 232
247 - /**  
248 - * @remark :更新blogTdk  
249 - * @name :updateBlogs  
250 - * @author :lyh  
251 - * @method :post  
252 - * @time :2023/8/19 10:07  
253 - */  
254 - public function updateBlogs($project_id){  
255 - echo date('Y-m-d H:i:s') . '更新博客--updateBlogs: 项目id' . $project_id . PHP_EOL;  
256 - $list = DB::connection('custom_mysql')->table('gl_blog')->where(['status'=>1,'project_id'=>$project_id])->get()->toArray();  
257 - if(!empty($list)){  
258 - foreach ($list as $k => $v){  
259 - $v = (array)$v;  
260 - echo date('Y-m-d H:i:s') . ' updateBlogs: ' . $v['id'] . PHP_EOL;  
261 - $data = [];  
262 - if(empty($v['seo_title'])){  
263 - $aiCommandModel = new AiCommand();  
264 - $AiInfo = $aiCommandModel->read(['key'=>'blog_seo_title'],['ai']);  
265 - if(!empty($AiInfo['ai'])){  
266 - $data['seo_title'] = $this->ai_send('blog_seo_title',$v['name']);  
267 - }else{  
268 - $data['seo_title'] = $v['name'];  
269 - }  
270 - }  
271 - if(empty($v['seo_keywords'])){  
272 - $data['seo_keywords'] = $this->ai_send('seo_keywords',$v['name']);  
273 - }  
274 - if(empty($v['seo_description'])){  
275 - $data['seo_description'] = $this->ai_send('seo_meta_description',$v['name']);  
276 - }  
277 - if(!$data){  
278 - continue;  
279 - }  
280 - DB::connection('custom_mysql')->table('gl_blog')->where(['id'=>$v['id']])->update($data); 233 + public function getPrompt($project_id, $prompt, $table, $data){
  234 + $lang = '';
  235 + if(strpos($prompt, '{topic}') !== false){
  236 + $topic = $data[$this->topic_fields[$table]] ?? '';
  237 + if(!$topic){
  238 + echo 'topic为空 跳过' . PHP_EOL;
  239 + return false;
281 } 240 }
  241 + $prompt = str_replace('{topic}', $topic, $prompt);
  242 + $lang = $this->getLang($topic);
282 } 243 }
283 - return true;  
284 - }  
285 -  
286 - /**  
287 - * @remark :更新新闻Tdk  
288 - * @name :updateNews  
289 - * @author :lyh  
290 - * @method :post  
291 - * @time :2023/8/19 10:06  
292 - */  
293 - public function updateBlogCate($project_id){  
294 - echo date('Y-m-d H:i:s') . '更新博客分类--updateBlogCate: 项目id' . $project_id . PHP_EOL;  
295 - $list = DB::connection('custom_mysql')->table('gl_blog_category')->where(['status'=>0,'project_id'=>$project_id])->get()->toArray();  
296 - if(!empty($list)){  
297 - foreach ($list as $k => $v){  
298 - $v = (array)$v;  
299 - echo date('Y-m-d H:i:s') . ' updateBlogCate: ' . $v['id'] . PHP_EOL;  
300 - $data = [];  
301 - if(empty($v['seo_title'])){  
302 - $data['seo_title'] = $v['name'];  
303 - }  
304 - if(empty($v['seo_keywords'])){  
305 - //获取核心关键词  
306 - $main_keyword = $this->mainKeywords($project_id);  
307 - if(!empty($main_keyword)){  
308 - $data['seo_keywords'] = $this->ai_send('seo_keywords',$main_keyword);  
309 - }  
310 - }  
311 - if(empty($v['seo_des'])){  
312 - $name = $this->companyName($project_id);  
313 - $data['seo_des'] = $this->ai_send('page_meta_description',$v['name'],$name);  
314 - }  
315 - if(!$data){  
316 - continue;  
317 - }  
318 - DB::connection('custom_mysql')->table('gl_blog_category')->where(['id'=>$v['id']])->update($data); 244 + if(strpos($prompt, '{keyword}') !== false) {
  245 + $keyword = $this->mainKeywords($project_id, 8);
  246 + if(!$keyword){
  247 + echo '核心关键词为空 跳过' . PHP_EOL;
  248 + return false;
319 } 249 }
  250 + $prompt = str_replace('{keyword}', $keyword, $prompt);
  251 + !$lang && $lang = $this->getLang($keyword);
320 } 252 }
321 - return true;  
322 - }  
323 -  
324 - /**  
325 - * @remark :单页面更新tdk  
326 - * @name :updatePage  
327 - * @author :lyh  
328 - * @method :post  
329 - * @time :2023/10/30 11:04  
330 - */  
331 - public function updatePage($project_id){  
332 - echo date('Y-m-d H:i:s') . '更新自定义界面--updatePage: 项目id' . $project_id . PHP_EOL;  
333 - $list = DB::connection('custom_mysql')->table('gl_web_custom_template')->select(['id','name','title','keywords','description','project_id'])->where(['project_id'=>$project_id])->get()->toArray();  
334 - if(!empty($list)){  
335 - foreach ($list as $v){  
336 - $v = (array)$v;  
337 - echo date('Y-m-d H:i:s') . ' updatePage: ' . $v['id'] . PHP_EOL;  
338 - $data = [];  
339 - if(empty($v['title'])){  
340 - //生成seo_title  
341 - $data['title'] = $v['name'];  
342 - }  
343 - if(empty($v['keywords'])){  
344 - //获取核心关键词  
345 - $main_keyword = $this->mainKeywords($project_id);  
346 - if(!empty($main_keyword)){  
347 - $data['keywords'] = $this->ai_send('seo_keywords',$main_keyword);  
348 - }  
349 - }  
350 - if(empty($v['description'])){  
351 - $name = $this->companyName($project_id);  
352 - if(!empty($name)){  
353 - $data['description'] = $this->ai_send('page_meta_description',$v['name'],$name);  
354 - }  
355 - }  
356 - if(!$data){  
357 - continue;  
358 - }  
359 - DB::connection('custom_mysql')->table('gl_web_custom_template')->where(['id'=>$v['id']])->update($data); 253 + if(strpos($prompt, '{company name}') !== false) {
  254 + $company_name = $this->companyName($project_id);
  255 + if(!$company_name){
  256 + echo '公司英文全称为空 跳过' . PHP_EOL;
  257 + return false;
360 } 258 }
  259 + $prompt = str_replace('{company name}', $company_name, $prompt);
361 } 260 }
362 - return true; 261 + $prompt .= '.Please answer in ' . ($lang ?: 'English');
  262 +
  263 + echo $prompt . PHP_EOL;
  264 +
  265 + return $prompt;
363 } 266 }
364 267
365 /** 268 /**
@@ -369,15 +272,16 @@ class UpdateSeoTdk extends Command @@ -369,15 +272,16 @@ class UpdateSeoTdk extends Command
369 * @method :post 272 * @method :post
370 * @time :2023/10/30 11:22 273 * @time :2023/10/30 11:22
371 */ 274 */
372 - public function companyName($project_id,$key = ''){ 275 + public function companyName($project_id, $key = '')
  276 + {
373 $data = [ 277 $data = [
374 'product_long_description', 278 'product_long_description',
375 ]; 279 ];
376 $projectOptimizeModel = new DeployOptimize(); 280 $projectOptimizeModel = new DeployOptimize();
377 - $info = $projectOptimizeModel->read(['project_id'=>$project_id],['id','company_en_name','company_en_description']);  
378 - if(in_array($key,$data)){ 281 + $info = $projectOptimizeModel->read(['project_id' => $project_id], ['id', 'company_en_name', 'company_en_description']);
  282 + if (in_array($key, $data)) {
379 return $info['company_en_description']; 283 return $info['company_en_description'];
380 - }else{ 284 + } else {
381 return $info['company_en_name']; 285 return $info['company_en_name'];
382 } 286 }
383 } 287 }
@@ -389,21 +293,31 @@ class UpdateSeoTdk extends Command @@ -389,21 +293,31 @@ class UpdateSeoTdk extends Command
389 * @method :post 293 * @method :post
390 * @time :2023/10/30 11:22 294 * @time :2023/10/30 11:22
391 */ 295 */
392 - public function mainKeywords($project_id){ 296 + public function mainKeywords($project_id, $num)
  297 + {
393 $str = ''; 298 $str = '';
394 $projectOptimizeModel = new DeployOptimize(); 299 $projectOptimizeModel = new DeployOptimize();
395 - $info = $projectOptimizeModel->read(['project_id'=>$project_id],['id','main_keywords']);  
396 - if($info !== false){  
397 - if(!empty($info['main_keywords'])){  
398 - $arr = explode(',',$info['main_keywords']);  
399 - if(isset($arr[0])){  
400 - $str = $arr[0];  
401 - }  
402 - } 300 + $info = $projectOptimizeModel->read(['project_id' => $project_id], ['id', 'main_keywords']);
  301 + if (!empty($info['main_keywords'])) {
  302 + $main_keywords = explode(',', $info['main_keywords']);
  303 + //随机取
  304 + shuffle($main_keywords);
  305 + $main_keywords = array_slice($main_keywords, 0, $num);
  306 + $str = implode(",", $main_keywords);
403 } 307 }
404 return $str; 308 return $str;
405 } 309 }
406 310
  311 + public function getLang($content){
  312 + $result = Translate::translateSl($content);
  313 + if (isset($result['texts']['sl']) && isset(Translate::$tls_list[$result['texts']['sl']])) {
  314 + $lang = Translate::$tls_list[$result['texts']['sl']]['lang_en'];
  315 + } else {
  316 + $lang = 'English';
  317 + }
  318 + return $lang;
  319 + }
  320 +
407 /** 321 /**
408 * @remark :AI发送 322 * @remark :AI发送
409 * @name :ai_send 323 * @name :ai_send
@@ -411,16 +325,11 @@ class UpdateSeoTdk extends Command @@ -411,16 +325,11 @@ class UpdateSeoTdk extends Command
411 * @method :post 325 * @method :post
412 * @time :2023/8/19 10:40 326 * @time :2023/8/19 10:40
413 */ 327 */
414 - public function ai_send($key,$keywords,$name = ''){  
415 - $chat_url = 'v2/openai_chat_qqs';  
416 - $param = [  
417 - 'key'=>$key,  
418 - 'keywords'=>$keywords,  
419 - ];  
420 - $data = Common::send_openai_msg($chat_url,$param,$name);  
421 - $data['text'] = Common::deal_keywords($data['text']);  
422 - $data['text'] = Common::deal_str($data['text']);  
423 - return $data['text']; 328 + public function ai_send($prompt)
  329 + {
  330 + $text = Gpt::instance()->openai_chat_qqs($prompt);
  331 + $text = Common::deal_keywords($text);
  332 + return Common::deal_str($text);
424 } 333 }
425 334
426 /** 335 /**
  1 +<?php
  2 +
  3 +namespace App\Helper;
  4 +
  5 +use Illuminate\Support\Facades\Http;
  6 +use Illuminate\Support\Facades\Log;
  7 +
  8 +
  9 +/**
  10 + * Class Gpt
  11 + * @package App\Helper
  12 + * @author zbj
  13 + * @date 2023/11/3
  14 + */
  15 +class Gpt
  16 +{
  17 + public $api = 'http://openai.waimaoq.com/';
  18 +
  19 + public $header = [];
  20 +
  21 + private static $instance;
  22 +
  23 + public static function instance(){
  24 + if(!self::$instance){
  25 + self::$instance = new static;
  26 + }
  27 + return self::$instance;
  28 + }
  29 +
  30 + /**
  31 + * 全球搜-文本生成接口。模型:gpt-3.5-turbo
  32 + * @author zbj
  33 + * @date 2023/8/25
  34 + *
  35 + */
  36 + public function openai_chat_qqs($content, $system_content = '')
  37 + {
  38 + $url = $this->api . 'v2/openai_chat_qqs';
  39 +
  40 + $data = [
  41 + 'messages' => [],
  42 + ];
  43 + if ($system_content) {
  44 + $data['messages'][] = [
  45 + "role" => "system",
  46 + "content" => $system_content
  47 + ];
  48 + }
  49 + $data['messages'][] = [
  50 + "role" => "user",
  51 + "content" => $content
  52 + ];
  53 +
  54 + $time = time();
  55 + try {
  56 + $result = Http::withHeaders($this->header)->withOptions(['verify' => false])->acceptJson()
  57 + ->withBody(json_encode($data, JSON_UNESCAPED_UNICODE), 'application/json')
  58 + ->post($url);
  59 + $json = $result->json();
  60 + if (!isset($json['text'])) {
  61 + Log::error('openai_chat_qqs data:', $data);
  62 + Log::error('openai_chat_qqs result:' . (time() - $time), $json === null ? ['null'] : $json);
  63 + }
  64 + } catch (\Throwable $e) {
  65 + Log::error('openai_chat_qqs time ' . (time() - $time) . ' error:' . $e->getMessage());
  66 + $json = [];
  67 + }
  68 + return $json['text'] ?? '';
  69 + }
  70 +
  71 +}
@@ -329,7 +329,7 @@ class BlogCategoryLogic extends BaseLogic @@ -329,7 +329,7 @@ class BlogCategoryLogic extends BaseLogic
329 329
330 $cate_arr = explode('/',$category); 330 $cate_arr = explode('/',$category);
331 $p_cate = $cate_arr[0]; 331 $p_cate = $cate_arr[0];
332 - $c_cate = $cate_arr[1]; 332 + $c_cate = $cate_arr[1]??'';
333 333
334 $p_category = $this->model->read(['name'=>$p_cate,'pid'=>0]); 334 $p_category = $this->model->read(['name'=>$p_cate,'pid'=>0]);
335 if(!$p_category){ 335 if(!$p_category){
@@ -295,7 +295,7 @@ class BlogLogic extends BaseLogic @@ -295,7 +295,7 @@ class BlogLogic extends BaseLogic
295 ] 295 ]
296 ); 296 );
297 //更新路由 297 //更新路由
298 - $route = RouteMap::setRoute((isset($data[1]) && $data[1]) ? $data[1] : $data[0], RouteMap::SOURCE_BLOG, $id, $project_id); 298 + $route = RouteMap::setRoute($data[1] ?: $data[0], RouteMap::SOURCE_BLOG, $id, $project_id);
299 $this->edit(['url' => $route], ['id' => $id]); 299 $this->edit(['url' => $route], ['id' => $id]);
300 300
301 return true; 301 return true;
@@ -311,7 +311,7 @@ class NewsCategoryLogic extends BaseLogic @@ -311,7 +311,7 @@ class NewsCategoryLogic extends BaseLogic
311 311
312 $cate_arr = explode('/',$category); 312 $cate_arr = explode('/',$category);
313 $p_cate = $cate_arr[0]; 313 $p_cate = $cate_arr[0];
314 - $c_cate = $cate_arr[1]; 314 + $c_cate = $cate_arr[1]??'';
315 315
316 $p_category = $this->model->read(['name'=>$p_cate,'pid'=>0]); 316 $p_category = $this->model->read(['name'=>$p_cate,'pid'=>0]);
317 if(!$p_category){ 317 if(!$p_category){
@@ -331,7 +331,7 @@ class NewsLogic extends BaseLogic @@ -331,7 +331,7 @@ class NewsLogic extends BaseLogic
331 ] 331 ]
332 ); 332 );
333 //更新路由 333 //更新路由
334 - $route = RouteMap::setRoute((isset($data[1]) && $data[1]) ? $data[1] : $data[0], RouteMap::SOURCE_NEWS, $id, $project_id); 334 + $route = RouteMap::setRoute($data[1] ?: $data[0], RouteMap::SOURCE_NEWS, $id, $project_id);
335 $this->edit(['url' => $route], ['id' => $id]); 335 $this->edit(['url' => $route], ['id' => $id]);
336 336
337 return true; 337 return true;
@@ -294,7 +294,7 @@ class CategoryLogic extends BaseLogic @@ -294,7 +294,7 @@ class CategoryLogic extends BaseLogic
294 294
295 $cate_arr = explode('/',$category); 295 $cate_arr = explode('/',$category);
296 $p_cate = $cate_arr[0]; 296 $p_cate = $cate_arr[0];
297 - $c_cate = $cate_arr[1]; 297 + $c_cate = $cate_arr[1]??'';
298 298
299 $p_category = $this->model->read(['title'=>$p_cate,'pid'=>0]); 299 $p_category = $this->model->read(['title'=>$p_cate,'pid'=>0]);
300 if(!$p_category){ 300 if(!$p_category){
@@ -549,7 +549,7 @@ class ProductLogic extends BaseLogic @@ -549,7 +549,7 @@ class ProductLogic extends BaseLogic
549 ] 549 ]
550 ); 550 );
551 //更新路由 551 //更新路由
552 - $route = RouteMap::setRoute((isset($data[1]) && $data[1]) ? $data[1] : $data[0], RouteMap::SOURCE_PRODUCT, $id, $project_id); 552 + $route = RouteMap::setRoute($data[1] ?: $data[0], RouteMap::SOURCE_PRODUCT, $id, $project_id);
553 $this->edit(['route' => $route], ['id' => $id]); 553 $this->edit(['route' => $route], ['id' => $id]);
554 554
555 return true; 555 return true;