作者 刘锟

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

@@ -114,7 +114,7 @@ class AiBlogAuthorTask extends Command @@ -114,7 +114,7 @@ class AiBlogAuthorTask extends Command
114 return true; 114 return true;
115 } 115 }
116 $aiBlogAuthorModel = new AiBlogAuthor(); 116 $aiBlogAuthorModel = new AiBlogAuthor();
117 - $info = $aiBlogAuthorModel->count(['project_id'=>$project_id]); 117 + $info = $aiBlogAuthorModel->counts(['project_id'=>$project_id]);
118 if($info === false){ 118 if($info === false){
119 foreach ($data as $v){ 119 foreach ($data as $v){
120 $param = [ 120 $param = [
  1 +<?php
  2 +
  3 +namespace App\Console\Commands\Ai;
  4 +
  5 +use App\Http\Logic\Aside\Project\ProjectLogic;
  6 +use App\Models\Ai\AiBlog;
  7 +use App\Models\Ai\AiBlogOpenLog;
  8 +use App\Models\Project\AiBlogTask as AiBlogTaskModel;
  9 +use App\Models\Project\Project;
  10 +use App\Models\Project\ProjectKeyword;
  11 +use App\Models\WebSetting\WebSetting;
  12 +use App\Services\AiBlogService;
  13 +use App\Services\ProjectServer;
  14 +use Illuminate\Console\Command;
  15 +use Illuminate\Support\Facades\DB;
  16 +use Illuminate\Support\Facades\Log;
  17 +
  18 +/**
  19 + * 自动发布AI博客任务
  20 + * Class AiBlogAutoPublish
  21 + * @package App\Console\Commands\Ai
  22 + * @author zbj
  23 + * @date 2025/3/6
  24 + */
  25 +class AiBlogAutoPublish extends Command
  26 +{
  27 + /**
  28 + * The name and signature of the console command.
  29 + *
  30 + * @var string
  31 + */
  32 + protected $signature = 'ai_blog_auto_publish {action}';
  33 +
  34 + /**
  35 + * The console command description.
  36 + *
  37 + * @var string
  38 + */
  39 + protected $description = '自动发布AI Blog';
  40 +
  41 +
  42 + /**
  43 + * @return bool
  44 + * @author zbj
  45 + * @date 2025/3/6
  46 + */
  47 + public function handle()
  48 + {
  49 + $action = $this->argument('action');
  50 + if($action == 'auto_publish'){
  51 + $this->auto_publish();
  52 + }
  53 + if($action == 'auto_open'){
  54 + $this->auto_open();
  55 + }
  56 + }
  57 +
  58 + public function auto_publish()
  59 + {
  60 + $this->output('开始自动发布博客文章');
  61 + $projects = Project::where('is_ai_blog', 1)->get();
  62 +
  63 + foreach ($projects as $project) {
  64 + $this->output("项目{$project->id}开始自动发布");
  65 + $next_auto_date = AiBlogTaskModel::where('project_id', $project->id)->where('type', 2)->whereNotNull('next_auto_date')->orderBy('id', 'desc')->value('next_auto_date');
  66 + if($next_auto_date && $next_auto_date > date('Y-m-d')){
  67 + $this->output("项目{$project->id}未到执行时间" . $next_auto_date);
  68 + continue;
  69 + }
  70 + //核心关键词+网站关键词
  71 + $main_keywords = ProjectKeyword::where('project_id', $project->id)->value('main_keyword');
  72 + $main_keywords = explode("\r\n", $main_keywords);
  73 + ProjectServer::useProject($project->id);
  74 + $site_keywords = WebSetting::where('project_id', $project->id)->value('keyword');
  75 + DB::disconnect('custom_mysql');
  76 + $site_keywords = explode(",", $site_keywords);
  77 + $keywords = array_filter(array_merge($main_keywords, $site_keywords));
  78 + $keywords = array_map('trim', $keywords);
  79 + if (empty($keywords)) {
  80 + $this->output("项目{$project->id}未获取到关键词");
  81 + }
  82 + $last_task = AiBlogTaskModel::where('project_id', $project->id)->where('type', 2)->orderBy('id', 'desc')->first();
  83 + //如果没有发布过AI blog任务, 第一次提交3个任务
  84 + if (!$last_task) {
  85 + for ($i = 0; $i < 3; $i++) {
  86 + $this->createTask($keywords, $project->id);
  87 + }
  88 + } else {
  89 + $this->createTask($keywords, $project->id);
  90 + }
  91 + }
  92 + }
  93 +
  94 + public function createTask($keywords, $project_id){
  95 + $keyword = $keywords[array_rand($keywords)];
  96 + $aiBlogService = new AiBlogService($project_id);
  97 + $result = $aiBlogService->setRoute($keyword)->createTask($keyword);
  98 + if ($result['status'] == 200) {
  99 + $aiBlogTaskModel = new AiBlogTaskModel();
  100 + $next_auto_date = date('Y-m-d', strtotime('+' . mt_rand(3,6) . 'days')); //每3-6天自动发布
  101 + $aiBlogTaskModel->addReturnId(['project_id' => $project_id, 'type' => 2, 'task_id' => $result['data']['task_id'], 'status' => 1, 'next_auto_date' => $next_auto_date]);
  102 +
  103 + ProjectServer::useProject($project_id);
  104 + $aiBlogModel = new AiBlog();
  105 +
  106 + $start = strtotime('10:00:00');
  107 + $end = strtotime('16:00:00');
  108 + $randomTimestamp = mt_rand($start, $end);
  109 + $created_at = date("Y-m-d H:i:s", $randomTimestamp);
  110 +
  111 + $aiBlogModel->addReturnId(['keyword' => $keyword, 'status' => 1, 'task_id' => $result['data']['task_id'], 'project_id' => $project_id, 'created_at' => $created_at]);
  112 + DB::disconnect('custom_mysql');
  113 + $this->output("任务创建成功");
  114 + } else {
  115 + $this->output('任务创建失败:' . json_encode($result));
  116 + }
  117 + }
  118 +
  119 + /**
  120 + * 上线的推广项目自动开启
  121 + * @author zbj
  122 + * @date 2025/3/7
  123 + */
  124 + public function auto_open()
  125 + {
  126 + $this->output('上线的推广项目自动开启');
  127 + $projects = Project::whereIn('type', [Project::TYPE_TWO, Project::TYPE_FOUR])
  128 + ->whereNotNull('uptime')->where('is_ai_blog', 0)
  129 + ->get();
  130 + foreach ($projects as $project) {
  131 + //未开启过 自动开启
  132 + if (!AiBlogOpenLog::isOpened($project->id)) {
  133 + //开启
  134 + $project->is_ai_blog = 1;
  135 + $project->save();
  136 + //创建AI博客项目
  137 + (new ProjectLogic())->setAiBlog($project->id, $project->main_lang_id, 1, $project->title);
  138 + //开启日志
  139 + AiBlogOpenLog::addLog($project->id);
  140 +
  141 + $this->output('自动开启项目:' . $project->id);
  142 + }
  143 + }
  144 + }
  145 +
  146 + /**
  147 + * 输出message
  148 + * @param $message
  149 + */
  150 + public function output($message)
  151 + {
  152 + Log::channel('ai_blog')->info($message);
  153 + echo date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL;
  154 + }
  155 +}
@@ -42,7 +42,7 @@ class AiBlogTask extends Command @@ -42,7 +42,7 @@ class AiBlogTask extends Command
42 public function handle(){ 42 public function handle(){
43 $aiBlogTaskModel = new AiBlogTaskModel(); 43 $aiBlogTaskModel = new AiBlogTaskModel();
44 while (true){ 44 while (true){
45 - $list = $aiBlogTaskModel->list(['status'=>1,'type'=>2],'id',['*'],'asc',1000); 45 + $list = $aiBlogTaskModel->list(['status'=>1,'type'=>2, 'created_at' => ['<', date('Y-m-d H:i:s')]],'id',['*'],'asc',1000);
46 if(empty($list)){ 46 if(empty($list)){
47 sleep(300); 47 sleep(300);
48 continue; 48 continue;
@@ -67,7 +67,7 @@ class GeneratePage extends Command @@ -67,7 +67,7 @@ class GeneratePage extends Command
67 $this->output($c_url . ' | 请求成功'); 67 $this->output($c_url . ' | 请求成功');
68 } else { 68 } else {
69 $noticeModel->edit(['status'=>2],['id'=>$noticeInfo['id']]); 69 $noticeModel->edit(['status'=>2],['id'=>$noticeInfo['id']]);
70 - $this->output($c_url . ' | ' . ($re['message'] ?? '未返回失败原因')); 70 + $this->output($c_url . ' | ' . (json_encode($re,true) ?? '未返回失败原因'));
71 } 71 }
72 $this->output(' taskID: ' . $noticeInfo['id'] . ' end'); 72 $this->output(' taskID: ' . $noticeInfo['id'] . ' end');
73 } catch (\Exception $e) { 73 } catch (\Exception $e) {
@@ -41,6 +41,9 @@ class Kernel extends ConsoleKernel @@ -41,6 +41,9 @@ class Kernel extends ConsoleKernel
41 $schedule->command('sync_inquiry_text')->dailyAt('09:00')->withoutOverlapping(1); 41 $schedule->command('sync_inquiry_text')->dailyAt('09:00')->withoutOverlapping(1);
42 //FB询盘费用同步 42 //FB询盘费用同步
43 $schedule->command('sync_ad_cost')->everyThirtyMinutes()->withoutOverlapping(1); 43 $schedule->command('sync_ad_cost')->everyThirtyMinutes()->withoutOverlapping(1);
  44 +
  45 +// $schedule->command('ai_blog_auto_publish auto_open')->everyMinute()->withoutOverlapping(1);
  46 +// $schedule->command('ai_blog_auto_publish auto_publish')->dailyAt('07:00')->withoutOverlapping(1);
44 } 47 }
45 48
46 /** 49 /**
@@ -300,9 +300,9 @@ class InquiryController extends BaseController @@ -300,9 +300,9 @@ class InquiryController extends BaseController
300 */ 300 */
301 public function tranCountry(InquiryLogic $logic){ 301 public function tranCountry(InquiryLogic $logic){
302 $this->request->validate([ 302 $this->request->validate([
303 - 'phone_region' => 'required', 303 + 'country_code' => 'required',
304 ],[ 304 ],[
305 - 'phone_region.required' => '国家译文不能为空' 305 + 'country_code.required' => '国家译文不能为空'
306 ]); 306 ]);
307 $data = $logic->tranCountry(); 307 $data = $logic->tranCountry();
308 $this->response('success',Code::SUCCESS,$data); 308 $this->response('success',Code::SUCCESS,$data);
@@ -76,7 +76,7 @@ class ProductController extends BaseController @@ -76,7 +76,7 @@ class ProductController extends BaseController
76 } 76 }
77 77
78 /** 78 /**
79 - * @remark :列表 79 + * @remark :下载列表
80 * @name :index 80 * @name :index
81 * @author :lyh 81 * @author :lyh
82 * @method :post 82 * @method :post
@@ -108,29 +108,6 @@ class ProductController extends BaseController @@ -108,29 +108,6 @@ class ProductController extends BaseController
108 } 108 }
109 $this->response('success',Code::SUCCESS,$lists); 109 $this->response('success',Code::SUCCESS,$lists);
110 } 110 }
111 - /**  
112 - * @remark :获取当前页的所有关键字名称  
113 - * @name :keywordNameLists  
114 - * @author :lyh  
115 - * @method :post  
116 - * @time :2024/6/3 14:24  
117 - */  
118 - public function keywordNameLists($lists){  
119 - $keywordId = [];  
120 - foreach ($lists as $v){  
121 - $keywordId = array_merge($keywordId,$v['keyword_id']);  
122 - }  
123 - $keywordId = array_values(array_unique($keywordId));  
124 - $keywordModel = new Keyword();  
125 - $data = [];  
126 - $cateList = $keywordModel->list(['id' => ['in',$keywordId]], ['id', 'title']);  
127 - if (!empty($cateList)) {  
128 - foreach ($cateList as $value) {  
129 - $data[$value['id']] = $value['title'];  
130 - }  
131 - }  
132 - return $data;  
133 - }  
134 111
135 /** 112 /**
136 * @remark :不分页产品列表 113 * @remark :不分页产品列表
@@ -146,424 +123,119 @@ class ProductController extends BaseController @@ -146,424 +123,119 @@ class ProductController extends BaseController
146 } 123 }
147 124
148 /** 125 /**
149 - * @remark :获取时处理图片和文件  
150 - * @name :getHandleFileImage 126 + * @remark :详情
  127 + * @name :info
151 * @author :lyh 128 * @author :lyh
152 * @method :post 129 * @method :post
153 - * @time :2024/1/23 17:43 130 + * @time :2023/8/21 18:12
154 */ 131 */
155 - public function getHandleFileImage($v){  
156 - //ToDo::处理图片及文件  
157 - if(!empty($v['thumb']) && !empty($v['thumb']['url'])){  
158 - $v['thumb']['url'] = getImageUrl($v['thumb']['url'],$this->user['storage_type'] ?? 0,$this->user['project_location']);  
159 - }  
160 - if(!empty($v['gallery'])){  
161 - foreach ($v['gallery'] as $gallery_k => $gallery_v){  
162 - $gallery_v['url'] = getImageUrl($gallery_v['url'],$this->user['storage_type'] ?? 0,$this->user['project_location']);  
163 - $v['gallery'][$gallery_k] = $gallery_v;  
164 - }  
165 - }  
166 - if(!empty($v['icon'])){  
167 - foreach ($v['icon'] as $icon_k => $icon_v){  
168 - $icon_v = getImageUrl($icon_v,$this->user['storage_type'] ?? 0,$this->user['project_location']);  
169 - $v['icon'][$icon_k] = $icon_v;  
170 - }  
171 - }  
172 - if(!empty($v['video'])){  
173 - $v['video']['url'] = getFileUrl($v['video']['url'],$this->user['storage_type'] ?? 0,$this->user['project_location'],$this->user['file_cdn'] ?? 0);  
174 - $v['video']['video_image'] = getImageUrl($v['video']['video_image'] ?? '',$this->user['storage_type'] ?? 0,$this->user['project_location']);  
175 - }  
176 - if(!empty($v['files']) && !empty($v['files']['url'])){  
177 - $v['files']['url'] = getFileUrl($v['files']['url'],$this->user['storage_type'] ?? 0,$this->user['project_location'],$this->user['file_cdn'] ?? 0);  
178 - }  
179 - return $this->success($v); 132 + public function info(Product $product){
  133 + $this->request->validate([
  134 + 'id'=>'required'
  135 + ],[
  136 + 'id.required' => 'ID不能为空'
  137 + ]);
  138 + $info = $product->read(['id'=>$this->param['id']]);
  139 + $info = $this->handleParam($info);
  140 + return $this->response('success',Code::SUCCESS,$info);
180 } 141 }
181 142
182 /** 143 /**
183 - * @remark :搜索参数处理  
184 - * @name :handleReturnParam 144 + * @remark :保存产品数据
  145 + * @name :save
185 * @author :lyh 146 * @author :lyh
186 * @method :post 147 * @method :post
187 - * @time :2023/9/14 10:01 148 + * @time :2023/8/17 15:01
188 */ 149 */
189 - public function searchParam(&$query){  
190 - $query = $query->where('project_id',$this->user['project_id']);  
191 - if (isset($this->map['category_id']) && !empty($this->map['category_id'])) {  
192 - $str[] = $this->map['category_id'];  
193 - $this->getAllSub($this->map['category_id'],$str);  
194 - $categoryRelatedModel = new CategoryRelated();  
195 - $product_id_arr = $categoryRelatedModel->whereIn('cate_id',$str)->pluck('product_id')->toArray();  
196 - $query = $query->whereIn('id',$product_id_arr);  
197 - }  
198 - if(isset($this->map['title']) && !empty($this->map['title'])){  
199 - $this->map['title'] = str_replace('+',' ',$this->map['title']);  
200 - $query = $query->where('title','like','%'.$this->map['title'].'%');  
201 - }  
202 - if(isset($this->map['keyword_title']) && !empty($this->map['keyword_title'])){  
203 - $keywordModel = new Keyword();  
204 - $keywordInfo = $keywordModel->read(['title'=>$this->map['keyword_title']],['id']);  
205 - if(!empty($keywordInfo)){  
206 - $query = $query->where('keyword_id','like','%,'.$keywordInfo['id'].',%');  
207 - }  
208 - }  
209 - if(isset($this->map['status'])){  
210 - if($this->map['status'] == 0){  
211 - $query = $query->whereIn('status',[0,3]);  
212 - }else{  
213 - $query = $query->where('status',$this->map['status']);  
214 - }  
215 - }  
216 - if(isset($this->map['created_uid'])){  
217 - $query = $query->where('created_uid',$this->map['created_uid']);  
218 - }  
219 - if(!empty($this->param['start_at']) && !empty($this->param['end_at'])){  
220 - if($this->user['project_id'] == 2059){  
221 - $query->where('send_time', '>=' ,$this->param['start_at'].' 00:00:00')->where('send_time', '<=' ,$this->param['end_at'].' 59:59:59');  
222 - }else{  
223 - $query->where('created_at', '>=' ,$this->param['start_at'].' 00:00:00')->where('created_at', '<=' ,$this->param['end_at'].' 59:59:59');  
224 - }  
225 - }  
226 - $this->param['featured_status'] = $this->param['featured_status'] ?? 0;  
227 - if($this->param['featured_status'] != Category::STATUS_ACTIVE) {  
228 - $cateModel = new Category();  
229 - $featured_ids = $cateModel->formatQuery(['title'=>['in',['Featured','featured']]])->pluck('id')->toArray();  
230 - if(!empty($featured_ids)){  
231 - $status = [];  
232 - if(isset($this->map['status'])){  
233 - $status = ['status'=>$this->map['status']];  
234 - }  
235 - $cateList = $cateModel->list($status,'id',['id','pid']);  
236 - //获取当前的子集  
237 - $featured_arr = [];  
238 - foreach ($featured_ids as $id){  
239 - $featured_arr = array_merge($featured_arr,array_unique(_get_all_sub($id,$cateList)));  
240 - }  
241 - if(!empty($featured_arr)){  
242 - $cateRelated = new CategoryRelated();  
243 - $product_ids = $cateRelated->whereIn('cate_id',$featured_arr)->pluck('product_id')->unique()->toArray();  
244 - $query = $query->whereNotIn('id',$product_ids);  
245 - }  
246 - }  
247 -  
248 - }  
249 - return $query; 150 + public function save(ProductRequest $request, ProductLogic $logic)
  151 + {
  152 + $request->validated();
  153 + $data = $logic->productSave();
  154 + $this->response('success',Code::SUCCESS,$data);
250 } 155 }
251 156
252 /** 157 /**
253 - * @remark :获取当前id下所有子集  
254 - * @name :getAllSub 158 + * @remark :直接编辑列表数据
  159 + * @name :editList
255 * @author :lyh 160 * @author :lyh
256 * @method :post 161 * @method :post
257 - * @time :2023/10/18 15:10 162 + * @time :2023/10/26 9:48
258 */ 163 */
259 - public function getAllSub($id,&$str = []){  
260 - $cateModel = new Category();  
261 - $list = $cateModel->list(['pid'=>$id,'status'=>1],['id','pid']);  
262 - if(!empty($list)){  
263 - foreach ($list as $v){  
264 - $str[] = $v['id'];  
265 - $this->getAllSub($v['id'],$str);  
266 - }  
267 - }  
268 - return $str; 164 + public function editList(ProductLogic $logic){
  165 + $logic->editList();
  166 + $this->response('success');
269 } 167 }
270 168
271 /** 169 /**
272 - * @remark :获取所有分类  
273 - * @name :getCategoryList 170 + * @remark :删除
  171 + * @name :delete
274 * @author :lyh 172 * @author :lyh
275 * @method :post 173 * @method :post
276 - * @time :2023/9/14 13:56 174 + * @time :2023/8/22 13:45
277 */ 175 */
278 - public function getCategoryList(){  
279 - $data = Common::get_user_cache('product_category',$this->user['project_id']);  
280 - if(empty($data)){  
281 - $categoryModel = new Category();  
282 - $data = [];  
283 - $cateList = $categoryModel->list(['project_id'=>$this->user['project_id']],['id','title']);  
284 - if(!empty($cateList)){  
285 - foreach ($cateList as $value){  
286 - $data[$value['id']] = $value['title'];  
287 - }  
288 - }  
289 - Common::set_user_cache($data,'product_category',$this->user['project_id']);  
290 - }  
291 - return $data; 176 + public function delete(ProductLogic $logic)
  177 + {
  178 + $this->request->validate([
  179 + 'ids'=>['required', new Ids()]
  180 + ],[
  181 + 'ids.required' => 'ID不能为空'
  182 + ]);
  183 + $logic->productDelete();
  184 + $this->response('success');
292 } 185 }
293 186
  187 +
294 /** 188 /**
295 - * @remark :获取分类名称  
296 - * @name :categoryName 189 + * @remark :根据状态获取数量
  190 + * @name :getStatusNumber
297 * @author :lyh 191 * @author :lyh
298 * @method :post 192 * @method :post
299 - * @time :2023/9/14 13:58 193 + * @time :2023/8/21 18:33
300 */ 194 */
301 - public function categoryName($product_id,$data){  
302 - $cateRelatedModel = new CategoryRelated();  
303 - $category_id = $cateRelatedModel->where('product_id',$product_id)->pluck('cate_id')->toArray();  
304 - $category_name = '';  
305 - if(!empty($category_id) && !empty($data)){  
306 - foreach ($category_id as $v){  
307 - if(isset($data[$v])){  
308 - $category_name .= $data[$v].',';  
309 - }  
310 - }  
311 - $category_name = trim($category_name,',');  
312 - }  
313 - return $category_name; 195 + public function getStatusNumber(ProductLogic $logic){
  196 + $this->request->validate([
  197 + 'featured_status'=>'numeric',
  198 + ],[
  199 + 'featured_status.numeric' => 'numeric为数字',
  200 + ]);
  201 + $data = $logic->getStatusNumber();
  202 + $this->response('success',Code::SUCCESS,$data);
314 } 203 }
315 204
316 /** 205 /**
317 - * @remark :获取关键词名称  
318 - * @name :categoryName 206 + * @remark :复制产品
  207 + * @name :copyProduct
319 * @author :lyh 208 * @author :lyh
320 * @method :post 209 * @method :post
321 - * @time :2023/9/14 13:58 210 + * @time :2023/7/29 14:59
322 */ 211 */
323 - public function keywordName($keyword_id,$data){  
324 - $keyword_name = '';  
325 - if(!empty($keyword_id) && !empty($data)){  
326 - foreach ($keyword_id as $v){  
327 - if(isset($data[$v])){  
328 - $keyword_name .= $data[$v].',';  
329 - }  
330 - }  
331 - $keyword_name = trim($keyword_name,',');  
332 - }  
333 - return $keyword_name; 212 + public function copyProduct(ProductLogic $logic){
  213 + $this->request->validate([
  214 + 'id'=>'required',
  215 + ],[
  216 + 'id.required' => 'id不能为空',
  217 + ]);
  218 + $data = $logic->setCopyProduct();
  219 + $this->response('success',Code::SUCCESS,$data);
334 } 220 }
335 221
336 /** 222 /**
337 - * @remark :详情  
338 - * @name :info 223 + * @remark :批量设置产品分类
  224 + * @name :batchSetCategory
339 * @author :lyh 225 * @author :lyh
340 * @method :post 226 * @method :post
341 - * @time :2023/8/21 18:12 227 + * @time :2023/8/15 17:51
342 */ 228 */
343 - public function info(Product $product){ 229 + public function batchSetCategory(ProductLogic $logic){
344 $this->request->validate([ 230 $this->request->validate([
345 - 'id'=>'required' 231 + 'id'=>'required',
  232 + 'category_id'=>'required',
346 ],[ 233 ],[
347 - 'id.required' => 'ID不能为空' 234 + 'id.required' => '产品ID不能为空',
  235 + 'category_id.required' => '分类ID不能为空',
348 ]); 236 ]);
349 - $info = $product->read(['id'=>$this->param['id']]);  
350 - $info = $this->handleParam($info);  
351 - return $this->response('success',Code::SUCCESS,$info);  
352 - }  
353 -  
354 - /**  
355 - * @remark :处理列表参数  
356 - * @name :handleParam  
357 - * @author :lyh  
358 - * @method :post  
359 - * @time :2023/8/17 9:15  
360 - */  
361 - public function handleParam($v){  
362 - $v['keyword_id_text'] = '';  
363 - if(!empty($v['keyword_id'])){  
364 - $keywordModel = new Keyword();  
365 - $keyword_data = $keywordModel->list(['id'=>['in',$v['keyword_id']]]);  
366 - foreach ($keyword_data as $v1){  
367 - $v['keyword_id_text'] .= $v1['title'].',';  
368 - }  
369 - $v['keyword_id_text'] = trim($v['keyword_id_text'],',');  
370 - }  
371 - if(!empty($v['status'])){  
372 - $v['status_text'] = Product::statusMap()[$v['status']] ?? '';  
373 - }else{  
374 - $v['status_text'] = '';  
375 - }  
376 - //ToDo::处理图片及文件  
377 - $v = $this->getHandleFileImage($v);  
378 - $template_id = $this->getTemplateId(BTemplate::SOURCE_PRODUCT,BTemplate::IS_DETAIL);  
379 - $v['is_renovation'] = $this->getIsRenovation(BTemplate::SOURCE_PRODUCT,BTemplate::IS_DETAIL,$template_id,$v['id'] ?? 0);  
380 - $v['url'] = $this->user['domain'].($v['route'] ?? '');  
381 - //获取当前数据扩展字段及值  
382 - $v['extend'] = $this->getExtendInfo($v['id']);  
383 - return $v;  
384 - }  
385 -  
386 -  
387 - /**  
388 - * @remark :获取扩展字段详情  
389 - * @name :getExtendInfo  
390 - * @author :lyh  
391 - * @method :post  
392 - * @time :2023/11/14 9:45  
393 - */  
394 - public function getExtendInfo($product_id){  
395 - $extendModel = new Extend();  
396 - $list = $extendModel->list([],'id',['id','type','key','title']);  
397 - if(empty($list)){  
398 - return [];  
399 - }  
400 - $extendInfoModel = new ExtendInfo();  
401 - $infoList = $extendInfoModel->list(['product_id'=>$product_id],'created_at');  
402 - foreach ($list as $k=>$v){  
403 - foreach ($infoList as $values){  
404 - if($v['key'] == $values['key']){  
405 - $v = $this->setTypValues($v,$values);  
406 - break;  
407 - }  
408 - }  
409 - $list[$k] = $v;  
410 - }  
411 - $list = $this->handleExtentList($list);  
412 - return $list;  
413 - }  
414 -  
415 - /**  
416 - * @remark :处理详情数据(初始化)  
417 - * @name :handleList  
418 - * @author :lyh  
419 - * @method :post  
420 - * @time :2024/8/14 18:26  
421 - */  
422 - public function handleExtentList($list){  
423 - foreach ($list as $k => $v){  
424 - if($v['type'] == 3 || $v['type'] == 4){  
425 - if(!isset($v['values'])){  
426 - $v['values'] = [];  
427 - }  
428 - }else{  
429 - if(!isset($v['values'])){  
430 - $v['values'] = '';  
431 - }  
432 - }  
433 - $list[$k] = $v;  
434 - }  
435 - return $this->success($list);  
436 - }  
437 - /**  
438 - * @remark :扩展字段根据type返回类型  
439 - * @name :setTypValues  
440 - * @author :lyh  
441 - * @method :post  
442 - * @time :2023/12/6 14:43  
443 - */  
444 - public function setTypValues($v,$info){  
445 - if($v['type'] == 3){  
446 - $arr = json_decode($info['values']);  
447 - foreach ($arr as $k1=>$v1){  
448 - $v1 = (array)$v1;  
449 - $v1['url'] = getImageUrl($v1['url'],$this->user['storage_type'],$this->user['project_location']);  
450 - $arr[$k1] = $v1;  
451 - }  
452 - $v['values'] = $arr;  
453 - }elseif($v['type'] == 4){  
454 - $arr1 = json_decode($info['values']);  
455 - foreach ($arr1 as $k1=>$v1){  
456 - $v1 = (array)$v1;  
457 - if(isset($v1['url'])){  
458 - $v1['url'] = getFileUrl($v1['url'],$this->user['storage_type'],$this->user['project_location'],$this->user['file_cdn'] ?? 0);  
459 - }else{  
460 - $v1 = getFileUrl($v1,$this->user['storage_type'],$this->user['project_location'],$this->user['file_cdn'] ?? 0);  
461 - }  
462 - $arr1[$k1] = $v1;  
463 - }  
464 - $v['values'] = $arr1;  
465 - }else{  
466 - $v['values'] = $info['values'];  
467 - }  
468 - return $v;  
469 - }  
470 -  
471 - /**  
472 - * @remark :保存产品数据  
473 - * @name :save  
474 - * @author :lyh  
475 - * @method :post  
476 - * @time :2023/8/17 15:01  
477 - */  
478 - public function save(ProductRequest $request, ProductLogic $logic)  
479 - {  
480 - $request->validated();  
481 - $data = $logic->productSave();  
482 - $this->response('success',Code::SUCCESS,$data);  
483 - }  
484 -  
485 - /**  
486 - * @remark :直接编辑列表数据  
487 - * @name :editList  
488 - * @author :lyh  
489 - * @method :post  
490 - * @time :2023/10/26 9:48  
491 - */  
492 - public function editList(ProductLogic $logic){  
493 - $logic->editList();  
494 - $this->response('success');  
495 - }  
496 -  
497 - /**  
498 - * @remark :删除  
499 - * @name :delete  
500 - * @author :lyh  
501 - * @method :post  
502 - * @time :2023/8/22 13:45  
503 - */  
504 - public function delete(ProductLogic $logic)  
505 - {  
506 - $this->request->validate([  
507 - 'ids'=>['required', new Ids()]  
508 - ],[  
509 - 'ids.required' => 'ID不能为空'  
510 - ]);  
511 - $logic->productDelete();  
512 - $this->response('success');  
513 - }  
514 -  
515 -  
516 - /**  
517 - * @remark :根据状态获取数量  
518 - * @name :getStatusNumber  
519 - * @author :lyh  
520 - * @method :post  
521 - * @time :2023/8/21 18:33  
522 - */  
523 - public function getStatusNumber(ProductLogic $logic){  
524 - $this->request->validate([  
525 - 'featured_status'=>'numeric',  
526 - ],[  
527 - 'featured_status.numeric' => 'numeric为数字',  
528 - ]);  
529 - $data = $logic->getStatusNumber();  
530 - $this->response('success',Code::SUCCESS,$data);  
531 - }  
532 -  
533 - /**  
534 - * @remark :复制产品  
535 - * @name :copyProduct  
536 - * @author :lyh  
537 - * @method :post  
538 - * @time :2023/7/29 14:59  
539 - */  
540 - public function copyProduct(ProductLogic $logic){  
541 - $this->request->validate([  
542 - 'id'=>'required',  
543 - ],[  
544 - 'id.required' => 'id不能为空',  
545 - ]);  
546 - $data = $logic->setCopyProduct();  
547 - $this->response('success',Code::SUCCESS,$data);  
548 - }  
549 -  
550 - /**  
551 - * @remark :批量设置产品分类  
552 - * @name :batchSetCategory  
553 - * @author :lyh  
554 - * @method :post  
555 - * @time :2023/8/15 17:51  
556 - */  
557 - public function batchSetCategory(ProductLogic $logic){  
558 - $this->request->validate([  
559 - 'id'=>'required',  
560 - 'category_id'=>'required',  
561 - ],[  
562 - 'id.required' => '产品ID不能为空',  
563 - 'category_id.required' => '分类ID不能为空',  
564 - ]);  
565 - $logic->batchSetCategory();  
566 - $this->response('success'); 237 + $logic->batchSetCategory();
  238 + $this->response('success');
567 } 239 }
568 240
569 /** 241 /**
@@ -812,4 +484,335 @@ class ProductController extends BaseController @@ -812,4 +484,335 @@ class ProductController extends BaseController
812 $logic->batchSetKeyword(); 484 $logic->batchSetKeyword();
813 $this->response('success'); 485 $this->response('success');
814 } 486 }
  487 +
  488 + /**
  489 + * @remark :获取所有分类
  490 + * @name :getCategoryList
  491 + * @author :lyh
  492 + * @method :post
  493 + * @time :2023/9/14 13:56
  494 + */
  495 + public function getCategoryList(){
  496 + $data = Common::get_user_cache('product_category',$this->user['project_id']);
  497 + if(empty($data)){
  498 + $categoryModel = new Category();
  499 + $data = [];
  500 + $cateList = $categoryModel->list(['project_id'=>$this->user['project_id']],['id','title']);
  501 + if(!empty($cateList)){
  502 + foreach ($cateList as $value){
  503 + $data[$value['id']] = $value['title'];
  504 + }
  505 + }
  506 + Common::set_user_cache($data,'product_category',$this->user['project_id']);
  507 + }
  508 + return $data;
  509 + }
  510 + /**
  511 + * @remark :获取当前页的所有关键字名称
  512 + * @name :keywordNameLists
  513 + * @author :lyh
  514 + * @method :post
  515 + * @time :2024/6/3 14:24
  516 + */
  517 + public function keywordNameLists($lists){
  518 + $keywordId = [];
  519 + foreach ($lists as $v){
  520 + $keywordId = array_merge($keywordId,$v['keyword_id']);
  521 + }
  522 + $keywordId = array_values(array_unique($keywordId));
  523 + $keywordModel = new Keyword();
  524 + $data = [];
  525 + $cateList = $keywordModel->list(['id' => ['in',$keywordId]], ['id', 'title']);
  526 + if (!empty($cateList)) {
  527 + foreach ($cateList as $value) {
  528 + $data[$value['id']] = $value['title'];
  529 + }
  530 + }
  531 + return $data;
  532 + }
  533 +
  534 + /**
  535 + * @remark :获取时处理图片和文件
  536 + * @name :getHandleFileImage
  537 + * @author :lyh
  538 + * @method :post
  539 + * @time :2024/1/23 17:43
  540 + */
  541 + public function getHandleFileImage($v){
  542 + //ToDo::处理图片及文件
  543 + if(!empty($v['thumb']) && !empty($v['thumb']['url'])){
  544 + $v['thumb']['url'] = getImageUrl($v['thumb']['url'],$this->user['storage_type'] ?? 0,$this->user['project_location']);
  545 + }
  546 + if(!empty($v['gallery'])){
  547 + foreach ($v['gallery'] as $gallery_k => $gallery_v){
  548 + $gallery_v['url'] = getImageUrl($gallery_v['url'],$this->user['storage_type'] ?? 0,$this->user['project_location']);
  549 + $v['gallery'][$gallery_k] = $gallery_v;
  550 + }
  551 + }
  552 + if(!empty($v['icon'])){
  553 + foreach ($v['icon'] as $icon_k => $icon_v){
  554 + $icon_v = getImageUrl($icon_v,$this->user['storage_type'] ?? 0,$this->user['project_location']);
  555 + $v['icon'][$icon_k] = $icon_v;
  556 + }
  557 + }
  558 + if(!empty($v['video'])){
  559 + $v['video']['url'] = getFileUrl($v['video']['url'],$this->user['storage_type'] ?? 0,$this->user['project_location'],$this->user['file_cdn'] ?? 0);
  560 + $v['video']['video_image'] = getImageUrl($v['video']['video_image'] ?? '',$this->user['storage_type'] ?? 0,$this->user['project_location']);
  561 + }
  562 + if(!empty($v['files']) && !empty($v['files']['url'])){
  563 + $v['files']['url'] = getFileUrl($v['files']['url'],$this->user['storage_type'] ?? 0,$this->user['project_location'],$this->user['file_cdn'] ?? 0);
  564 + }
  565 + return $this->success($v);
  566 + }
  567 +
  568 + /**
  569 + * @remark :处理详情数据(初始化)
  570 + * @name :handleList
  571 + * @author :lyh
  572 + * @method :post
  573 + * @time :2024/8/14 18:26
  574 + */
  575 + public function handleExtentList($list){
  576 + foreach ($list as $k => $v){
  577 + if($v['type'] == 3 || $v['type'] == 4){
  578 + if(!isset($v['values'])){
  579 + $v['values'] = [];
  580 + }
  581 + }else{
  582 + if(!isset($v['values'])){
  583 + $v['values'] = '';
  584 + }
  585 + }
  586 + $list[$k] = $v;
  587 + }
  588 + return $this->success($list);
  589 + }
  590 +
  591 + /**
  592 + * @remark :扩展字段根据type返回类型
  593 + * @name :setTypValues
  594 + * @author :lyh
  595 + * @method :post
  596 + * @time :2023/12/6 14:43
  597 + */
  598 + public function setTypValues($v,$info){
  599 + if($v['type'] == 3){
  600 + $arr = json_decode($info['values']);
  601 + foreach ($arr as $k1=>$v1){
  602 + $v1 = (array)$v1;
  603 + $v1['url'] = getImageUrl($v1['url'],$this->user['storage_type'],$this->user['project_location']);
  604 + $arr[$k1] = $v1;
  605 + }
  606 + $v['values'] = $arr;
  607 + }elseif($v['type'] == 4){
  608 + $arr1 = json_decode($info['values']);
  609 + foreach ($arr1 as $k1=>$v1){
  610 + $v1 = (array)$v1;
  611 + if(isset($v1['url'])){
  612 + $v1['url'] = getFileUrl($v1['url'],$this->user['storage_type'],$this->user['project_location'],$this->user['file_cdn'] ?? 0);
  613 + }else{
  614 + $v1 = getFileUrl($v1,$this->user['storage_type'],$this->user['project_location'],$this->user['file_cdn'] ?? 0);
  615 + }
  616 + $arr1[$k1] = $v1;
  617 + }
  618 + $v['values'] = $arr1;
  619 + }else{
  620 + $v['values'] = $info['values'];
  621 + }
  622 + return $this->success($v);
  623 + }
  624 +
  625 + /**
  626 + * @remark :搜索参数处理
  627 + * @name :handleReturnParam
  628 + * @author :lyh
  629 + * @method :post
  630 + * @time :2023/9/14 10:01
  631 + */
  632 + public function searchParam(&$query){
  633 + $query = $query->where('project_id',$this->user['project_id']);
  634 + if (isset($this->map['category_id']) && !empty($this->map['category_id'])) {
  635 + $str[] = $this->map['category_id'];
  636 + $this->getAllSub($this->map['category_id'],$str);
  637 + $categoryRelatedModel = new CategoryRelated();
  638 + $product_id_arr = $categoryRelatedModel->whereIn('cate_id',$str)->pluck('product_id')->toArray();
  639 + $query = $query->whereIn('id',$product_id_arr);
  640 + }
  641 + if(isset($this->map['title']) && !empty($this->map['title'])){
  642 + $this->map['title'] = str_replace('+',' ',$this->map['title']);
  643 + $query = $query->where('title','like','%'.$this->map['title'].'%');
  644 + }
  645 + if(isset($this->map['keyword_title']) && !empty($this->map['keyword_title'])){
  646 + $keywordModel = new Keyword();
  647 + $keywordInfo = $keywordModel->read(['title'=>$this->map['keyword_title']],['id']);
  648 + if(!empty($keywordInfo)){
  649 + $query = $query->where('keyword_id','like','%,'.$keywordInfo['id'].',%');
  650 + }
  651 + }
  652 + if(isset($this->map['status'])){
  653 + if($this->map['status'] == 0){
  654 + $query = $query->whereIn('status',[0,3]);
  655 + }else{
  656 + $query = $query->where('status',$this->map['status']);
  657 + }
  658 + }
  659 + if(isset($this->map['created_uid'])){
  660 + $query = $query->where('created_uid',$this->map['created_uid']);
  661 + }
  662 + if(!empty($this->param['start_at']) && !empty($this->param['end_at'])){
  663 + if($this->user['project_id'] == 2059){
  664 + $query->where('send_time', '>=' ,$this->param['start_at'].' 00:00:00')->where('send_time', '<=' ,$this->param['end_at'].' 59:59:59');
  665 + }else{
  666 + $query->where('created_at', '>=' ,$this->param['start_at'].' 00:00:00')->where('created_at', '<=' ,$this->param['end_at'].' 59:59:59');
  667 + }
  668 + }
  669 + $this->param['featured_status'] = $this->param['featured_status'] ?? 0;
  670 + if($this->param['featured_status'] != Category::STATUS_ACTIVE) {
  671 + $cateModel = new Category();
  672 + $featured_ids = $cateModel->formatQuery(['title'=>['in',['Featured','featured']]])->pluck('id')->toArray();
  673 + if(!empty($featured_ids)){
  674 + $status = [];
  675 + if(isset($this->map['status'])){
  676 + $status = ['status'=>$this->map['status']];
  677 + }
  678 + $cateList = $cateModel->list($status,'id',['id','pid']);
  679 + //获取当前的子集
  680 + $featured_arr = [];
  681 + foreach ($featured_ids as $id){
  682 + $featured_arr = array_merge($featured_arr,array_unique(_get_all_sub($id,$cateList)));
  683 + }
  684 + if(!empty($featured_arr)){
  685 + $cateRelated = new CategoryRelated();
  686 + $product_ids = $cateRelated->whereIn('cate_id',$featured_arr)->pluck('product_id')->unique()->toArray();
  687 + $query = $query->whereNotIn('id',$product_ids);
  688 + }
  689 + }
  690 + }
  691 + return $query;
  692 + }
  693 +
  694 +
  695 + /**
  696 + * @remark :处理列表参数
  697 + * @name :handleParam
  698 + * @author :lyh
  699 + * @method :post
  700 + * @time :2023/8/17 9:15
  701 + */
  702 + public function handleParam($v){
  703 + $v['keyword_id_text'] = '';
  704 + if(!empty($v['keyword_id'])){
  705 + $keywordModel = new Keyword();
  706 + $keyword_data = $keywordModel->list(['id'=>['in',$v['keyword_id']]]);
  707 + foreach ($keyword_data as $v1){
  708 + $v['keyword_id_text'] .= $v1['title'].',';
  709 + }
  710 + $v['keyword_id_text'] = trim($v['keyword_id_text'],',');
  711 + }
  712 + if(!empty($v['status'])){
  713 + $v['status_text'] = Product::statusMap()[$v['status']] ?? '';
  714 + }else{
  715 + $v['status_text'] = '';
  716 + }
  717 + //ToDo::处理图片及文件
  718 + $v = $this->getHandleFileImage($v);
  719 + $template_id = $this->getTemplateId(BTemplate::SOURCE_PRODUCT,BTemplate::IS_DETAIL);
  720 + $v['is_renovation'] = $this->getIsRenovation(BTemplate::SOURCE_PRODUCT,BTemplate::IS_DETAIL,$template_id,$v['id'] ?? 0);
  721 + $v['url'] = $this->user['domain'].($v['route'] ?? '');
  722 + //获取当前数据扩展字段及值
  723 + $v['extend'] = $this->getExtendInfo($v['id']);
  724 + return $v;
  725 + }
  726 +
  727 +
  728 + /**
  729 + * @remark :获取扩展字段详情
  730 + * @name :getExtendInfo
  731 + * @author :lyh
  732 + * @method :post
  733 + * @time :2023/11/14 9:45
  734 + */
  735 + public function getExtendInfo($product_id){
  736 + $extendModel = new Extend();
  737 + $list = $extendModel->list([],'id',['id','type','key','title']);
  738 + if(empty($list)){
  739 + return [];
  740 + }
  741 + $extendInfoModel = new ExtendInfo();
  742 + $infoList = $extendInfoModel->list(['product_id'=>$product_id],'created_at');
  743 + foreach ($list as $k=>$v){
  744 + foreach ($infoList as $values){
  745 + if($v['key'] == $values['key']){
  746 + $v = $this->setTypValues($v,$values);
  747 + break;
  748 + }
  749 + }
  750 + $list[$k] = $v;
  751 + }
  752 + $list = $this->handleExtentList($list);
  753 + return $list;
  754 + }
  755 +
  756 + /**
  757 + * @remark :获取当前id下所有子集
  758 + * @name :getAllSub
  759 + * @author :lyh
  760 + * @method :post
  761 + * @time :2023/10/18 15:10
  762 + */
  763 + public function getAllSub($id,&$str = []){
  764 + $cateModel = new Category();
  765 + $list = $cateModel->list(['pid'=>$id,'status'=>1],['id','pid']);
  766 + if(!empty($list)){
  767 + foreach ($list as $v){
  768 + $str[] = $v['id'];
  769 + $this->getAllSub($v['id'],$str);
  770 + }
  771 + }
  772 + return $str;
  773 + }
  774 +
  775 +
  776 +
  777 + /**
  778 + * @remark :获取分类名称
  779 + * @name :categoryName
  780 + * @author :lyh
  781 + * @method :post
  782 + * @time :2023/9/14 13:58
  783 + */
  784 + public function categoryName($product_id,$data){
  785 + $cateRelatedModel = new CategoryRelated();
  786 + $category_id = $cateRelatedModel->where('product_id',$product_id)->pluck('cate_id')->toArray();
  787 + $category_name = '';
  788 + if(!empty($category_id) && !empty($data)){
  789 + foreach ($category_id as $v){
  790 + if(isset($data[$v])){
  791 + $category_name .= $data[$v].',';
  792 + }
  793 + }
  794 + $category_name = trim($category_name,',');
  795 + }
  796 + return $category_name;
  797 + }
  798 +
  799 + /**
  800 + * @remark :获取关键词名称
  801 + * @name :categoryName
  802 + * @author :lyh
  803 + * @method :post
  804 + * @time :2023/9/14 13:58
  805 + */
  806 + public function keywordName($keyword_id,$data){
  807 + $keyword_name = '';
  808 + if(!empty($keyword_id) && !empty($data)){
  809 + foreach ($keyword_id as $v){
  810 + if(isset($data[$v])){
  811 + $keyword_name .= $data[$v].',';
  812 + }
  813 + }
  814 + $keyword_name = trim($keyword_name,',');
  815 + }
  816 + return $keyword_name;
  817 + }
815 } 818 }
@@ -23,8 +23,8 @@ class WebSettingSeoController extends BaseController @@ -23,8 +23,8 @@ class WebSettingSeoController extends BaseController
23 * @time :2023/9/11 16:31 23 * @time :2023/9/11 16:31
24 */ 24 */
25 public function info(WebSettingSeoLogic $logic){ 25 public function info(WebSettingSeoLogic $logic){
26 - $info = $logic->seoInfo();  
27 - $this->response('success',Code::SUCCESS,$info); 26 + $result = $logic->seoInfo();
  27 + $this->response('success',Code::SUCCESS,$result);
28 } 28 }
29 29
30 /** 30 /**
@@ -35,7 +35,7 @@ class WebSettingSeoController extends BaseController @@ -35,7 +35,7 @@ class WebSettingSeoController extends BaseController
35 * @time :2023/9/11 16:32 35 * @time :2023/9/11 16:32
36 */ 36 */
37 public function save(WebSettingSeoLogic $logic){ 37 public function save(WebSettingSeoLogic $logic){
38 - $logic->seoSave();  
39 - $this->response('success'); 38 + $result = $logic->seoSave();
  39 + $this->response('success',Code::SUCCESS,$result);
40 } 40 }
41 } 41 }
@@ -7,6 +7,7 @@ use App\Helper\FormGlobalsoApi; @@ -7,6 +7,7 @@ use App\Helper\FormGlobalsoApi;
7 use App\Helper\Translate; 7 use App\Helper\Translate;
8 use App\Http\Logic\Aside\Project\ProjectLogic; 8 use App\Http\Logic\Aside\Project\ProjectLogic;
9 use App\Http\Logic\Bside\BaseLogic; 9 use App\Http\Logic\Bside\BaseLogic;
  10 +use App\Models\Com\WordCountry;
10 use App\Models\Domain\DomainInfo; 11 use App\Models\Domain\DomainInfo;
11 use App\Models\Inquiry\InquiryForm; 12 use App\Models\Inquiry\InquiryForm;
12 use App\Models\Inquiry\InquiryFormData; 13 use App\Models\Inquiry\InquiryFormData;
@@ -195,7 +196,7 @@ class InquiryLogic extends BaseLogic @@ -195,7 +196,7 @@ class InquiryLogic extends BaseLogic
195 public function sendMobileVerifyData($phone){ 196 public function sendMobileVerifyData($phone){
196 $phoneDataModel = new PhoneData(); 197 $phoneDataModel = new PhoneData();
197 $num_phone = preg_replace('/\D/', '',$phone) ?? ''; // \D 匹配所有非数字字符 198 $num_phone = preg_replace('/\D/', '',$phone) ?? ''; // \D 匹配所有非数字字符
198 - $data = $phoneDataModel->read(['num_phone'=>$num_phone]); 199 + $data = $phoneDataModel->read(['phone'=>$phone]);
199 if($data === false){ 200 if($data === false){
200 $url = 'https://fob.ai.cc/api/mobile_verify_data/'.$num_phone; 201 $url = 'https://fob.ai.cc/api/mobile_verify_data/'.$num_phone;
201 $data = http_get($url); 202 $data = http_get($url);
@@ -212,8 +213,12 @@ class InquiryLogic extends BaseLogic @@ -212,8 +213,12 @@ class InquiryLogic extends BaseLogic
212 'country_code'=>$data['country_code'] ?? '', 213 'country_code'=>$data['country_code'] ?? '',
213 'phone_region'=>$data['phone_region'] ?? '', 214 'phone_region'=>$data['phone_region'] ?? '',
214 ]; 215 ];
215 - if(!empty($param['phone_region'])){  
216 - $param['country'] = Translate::tran($param['phone_region'], 'zh') ?? ''; 216 + if(!empty($param['country_code'])){
  217 + $wordCountryModel = new WordCountry();
  218 + $info = $wordCountryModel->read(['pid'=>0,'iso2'=>$this->param['country_code']],['chinese_name']);
  219 + if($info !== false){
  220 + $param['country'] = $info['chinese_name'];
  221 + }
217 } 222 }
218 (new PhoneData())->addReturnId($param); 223 (new PhoneData())->addReturnId($param);
219 return $this->success($param); 224 return $this->success($param);
@@ -228,13 +233,18 @@ class InquiryLogic extends BaseLogic @@ -228,13 +233,18 @@ class InquiryLogic extends BaseLogic
228 * @author :lyh 233 * @author :lyh
229 * @method :post 234 * @method :post
230 * @time :2025/3/11 14:11 235 * @time :2025/3/11 14:11
  236 + * @param :pid:0->国家
231 */ 237 */
232 public function tranCountry(){ 238 public function tranCountry(){
233 - $country = Translate::tran($this->param['phone_region'], 'zh') ?? '';  
234 - if(!empty($country)){  
235 - $phoneDataModel = new PhoneData();  
236 - $phoneDataModel->edit(['country'=>$country],['phone_region'=>$this->param['phone_region']]); 239 + $wordCountryModel = new WordCountry();
  240 + $info = $wordCountryModel->read(['pid'=>0,'iso2'=>$this->param['country_code']],['chinese_name']);
  241 + if($info !== false){
  242 + $chinese_name = $info['chinese_name'];
  243 + }else{
  244 + $chinese_name = $this->param['country_code'];
237 } 245 }
238 - return $this->success(['country'=>$country]); 246 + $phoneDataModel = new PhoneData();
  247 + $phoneDataModel->edit(['country'=>$info['chinese_name']],['country_code'=>$this->param['country_code']]);
  248 + return $this->success(['country'=>$chinese_name]);
239 } 249 }
240 } 250 }
@@ -1154,4 +1154,5 @@ class ProductLogic extends BaseLogic @@ -1154,4 +1154,5 @@ class ProductLogic extends BaseLogic
1154 } 1154 }
1155 return $this->success(); 1155 return $this->success();
1156 } 1156 }
  1157 +
1157 } 1158 }
@@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
9 9
10 namespace App\Http\Logic\Bside\Setting; 10 namespace App\Http\Logic\Bside\Setting;
11 11
  12 +use App\Helper\Arr;
12 use App\Http\Logic\Bside\BaseLogic; 13 use App\Http\Logic\Bside\BaseLogic;
13 use App\Models\WebSetting\WebSettingSeo; 14 use App\Models\WebSetting\WebSettingSeo;
14 15
@@ -42,8 +43,11 @@ class WebSettingSeoLogic extends BaseLogic @@ -42,8 +43,11 @@ class WebSettingSeoLogic extends BaseLogic
42 * @author :lyh 43 * @author :lyh
43 * @method :post 44 * @method :post
44 * @time :2023/9/11 16:34 45 * @time :2023/9/11 16:34
  46 + * @param :product_category_prefix->分类页前缀;product_category_suffix->分类页后缀
45 */ 47 */
46 public function seoSave(){ 48 public function seoSave(){
  49 + $this->param['product_category_prefix'] = Arr::a2s($this->param['product_category_prefix'] ?? []);
  50 + $this->param['product_category_suffix'] = Arr::a2s($this->param['product_category_suffix'] ?? []);
47 try { 51 try {
48 $info = $this->model->read(['project_id'=>$this->user['project_id']]); 52 $info = $this->model->read(['project_id'=>$this->user['project_id']]);
49 if($info === false){ 53 if($info === false){
  1 +<?php
  2 +
  3 +namespace App\Models\Ai;
  4 +
  5 +use App\Models\Base;
  6 +
  7 +/**
  8 + * AI Blog开启日志
  9 + * Class AiBlogOpenLog
  10 + * @package App\Models\Ai
  11 + * @author zbj
  12 + * @date 2025/3/7
  13 + */
  14 +class AiBlogOpenLog extends Base
  15 +{
  16 + protected $table = 'gl_ai_blog_open_log';
  17 +
  18 +
  19 + public static function addLog($project_id, $manage_id = 0, $status = 1){
  20 + $log = new self();
  21 + $log->project_id = $project_id;
  22 + $log->manage_id = $manage_id;
  23 + $log->status = $status;
  24 + $log->save();
  25 + }
  26 +
  27 + /**
  28 + * 是否有开启记录
  29 + * @author zbj
  30 + * @date 2025/3/7
  31 + */
  32 + public static function isOpened($project_id){
  33 + $model = self::where('project_id', $project_id)->where('status', 1)->first();
  34 + return (bool)$model;
  35 + }
  36 +}
@@ -110,7 +110,7 @@ class Base extends Model @@ -110,7 +110,7 @@ class Base extends Model
110 */ 110 */
111 public function addReturnId($data){ 111 public function addReturnId($data){
112 $data = $this->filterRequestData($data); 112 $data = $this->filterRequestData($data);
113 - $data['created_at'] = date('Y-m-d H:i:s'); 113 + $data['created_at'] = $data['created_at'] ?? date('Y-m-d H:i:s');
114 $data['updated_at'] = $data['created_at']; 114 $data['updated_at'] = $data['created_at'];
115 return $this->insertGetId($data); 115 return $this->insertGetId($data);
116 } 116 }
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :WordCountry.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/3/11 17:24
  8 + */
  9 +
  10 +namespace App\Models\Com;
  11 +
  12 +use App\Models\Base;
  13 +
  14 +/**
  15 + * @remark :国家信息
  16 + * @name :WordCountry
  17 + * @author :lyh
  18 + * @method :post
  19 + * @time :2025/3/11 17:24
  20 + */
  21 +class WordCountry extends Base
  22 +{
  23 + protected $table = 'gl_world_country_city';
  24 +}
@@ -7,72 +7,6 @@ use App\Models\Base; @@ -7,72 +7,6 @@ use App\Models\Base;
7 use Illuminate\Database\Eloquent\Relations\BelongsToMany; 7 use Illuminate\Database\Eloquent\Relations\BelongsToMany;
8 use Illuminate\Database\Eloquent\SoftDeletes; 8 use Illuminate\Database\Eloquent\SoftDeletes;
9 9
10 -/**  
11 - * App\Models\Product\Product  
12 - *  
13 - * @method static get()  
14 - * @property int $id  
15 - * @property int $project_id  
16 - * @property string $title  
17 - * @property string $thumb 封面  
18 - * @property mixed|null $gallery 图集  
19 - * @property mixed|null $attrs 属性参数  
20 - * @property string|null $attr_id 通用参数  
21 - * @property string|null $category_id 分类 多个,号隔开  
22 - * @property string|null $keyword_id 关键词标签 多个,号隔开  
23 - * @property string|null $intro 简介  
24 - * @property string|null $content 详情  
25 - * @property mixed|null $describe 描述  
26 - * @property string $describe_id 通用描述  
27 - * @property mixed|null $seo_mate seo tdk  
28 - * @property string $related_product_id 相关产品 多个,号隔开  
29 - * @property int $sort 排序  
30 - * @property int $status 状态 0草稿 1已上架 2已下架  
31 - * @property int $created_uid 创建者  
32 - * @property \Illuminate\Support\Carbon|null $created_at  
33 - * @property \Illuminate\Support\Carbon|null $updated_at  
34 - * @property \Illuminate\Support\Carbon|null $deleted_at  
35 - * @property string|null $route 路由  
36 - * @property mixed|null $icon 图标  
37 - * @property string|null $product_type 产品类型:1,一般产品;2:推荐产品(recommend);3:热销产品(hot)  
38 - * @property int $is_upgrade 0:6.0 1:4.0,5.0升级  
39 - * @property string|null $send_time 发布时间  
40 - * @property int|null $six_read 1:导入数据可按6.0显示  
41 - * @method \Illuminate\Database\Eloquent\Builder|Product newModelQuery()  
42 - * @method \Illuminate\Database\Eloquent\Builder|Product newQuery()  
43 - * @method \Illuminate\Database\Eloquent\Builder|Product onlyTrashed()  
44 - * @method static \Illuminate\Database\Eloquent\Builder|Product query()  
45 - * @method \Illuminate\Database\Eloquent\Builder|Product whereAttrId($value)  
46 - * @method \Illuminate\Database\Eloquent\Builder|Product whereAttrs($value)  
47 - * @method \Illuminate\Database\Eloquent\Builder|Product whereCategoryId($value)  
48 - * @method \Illuminate\Database\Eloquent\Builder|Product whereContent($value)  
49 - * @method \Illuminate\Database\Eloquent\Builder|Product whereCreatedAt($value)  
50 - * @method \Illuminate\Database\Eloquent\Builder|Product whereCreatedUid($value)  
51 - * @method \Illuminate\Database\Eloquent\Builder|Product whereDeletedAt($value)  
52 - * @method \Illuminate\Database\Eloquent\Builder|Product whereDescribe($value)  
53 - * @method \Illuminate\Database\Eloquent\Builder|Product whereDescribeId($value)  
54 - * @method \Illuminate\Database\Eloquent\Builder|Product whereGallery($value)  
55 - * @method \Illuminate\Database\Eloquent\Builder|Product whereIcon($value)  
56 - * @method \Illuminate\Database\Eloquent\Builder|Product whereId($value)  
57 - * @method \Illuminate\Database\Eloquent\Builder|Product whereIntro($value)  
58 - * @method \Illuminate\Database\Eloquent\Builder|Product whereIsUpgrade($value)  
59 - * @method \Illuminate\Database\Eloquent\Builder|Product whereKeywordId($value)  
60 - * @method \Illuminate\Database\Eloquent\Builder|Product whereProductType($value)  
61 - * @method \Illuminate\Database\Eloquent\Builder|Product whereProjectId($value)  
62 - * @method \Illuminate\Database\Eloquent\Builder|Product whereRelatedProductId($value)  
63 - * @method \Illuminate\Database\Eloquent\Builder|Product whereRoute($value)  
64 - * @method \Illuminate\Database\Eloquent\Builder|Product whereSendTime($value)  
65 - * @method \Illuminate\Database\Eloquent\Builder|Product whereSeoMate($value)  
66 - * @method \Illuminate\Database\Eloquent\Builder|Product whereSixRead($value)  
67 - * @method \Illuminate\Database\Eloquent\Builder|Product whereSort($value)  
68 - * @method \Illuminate\Database\Eloquent\Builder|Product whereStatus($value)  
69 - * @method \Illuminate\Database\Eloquent\Builder|Product whereThumb($value)  
70 - * @method \Illuminate\Database\Eloquent\Builder|Product whereTitle($value)  
71 - * @method \Illuminate\Database\Eloquent\Builder|Product whereUpdatedAt($value)  
72 - * @method \Illuminate\Database\Eloquent\Builder|Product withTrashed()  
73 - * @method \Illuminate\Database\Eloquent\Builder|Product withoutTrashed()  
74 - * @mixin \Eloquent  
75 - */  
76 class Product extends Base 10 class Product extends Base
77 { 11 {
78 use SoftDeletes; 12 use SoftDeletes;
@@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
9 9
10 namespace App\Models\WebSetting; 10 namespace App\Models\WebSetting;
11 11
  12 +use App\Helper\Arr;
12 use App\Models\Base; 13 use App\Models\Base;
13 14
14 class WebSettingSeo extends Base 15 class WebSettingSeo extends Base
@@ -18,4 +19,32 @@ class WebSettingSeo extends Base @@ -18,4 +19,32 @@ class WebSettingSeo extends Base
18 19
19 //连接数据库 20 //连接数据库
20 protected $connection = 'custom_mysql'; 21 protected $connection = 'custom_mysql';
  22 +
  23 + /**
  24 + * @remark :(获取器)分类页前缀
  25 + * @name :getProductCategoryPrefixAttribute
  26 + * @author :lyh
  27 + * @method :post
  28 + * @time :2025/3/12 10:37
  29 + */
  30 + public function getProductCategoryPrefixAttribute($value){
  31 + if(!empty($value)){
  32 + $value = Arr::s2a($value);
  33 + }
  34 + return $value;
  35 + }
  36 +
  37 + /**
  38 + * @remark :(获取器)分类页后缀
  39 + * @name :getProductCategorySuffixAttribute
  40 + * @author :lyh
  41 + * @method :post
  42 + * @time :2025/3/12 10:38
  43 + */
  44 + public function getProductCategorySuffixAttribute($value){
  45 + if(!empty($value)){
  46 + $value = Arr::s2a($value);
  47 + }
  48 + return $value;
  49 + }
21 } 50 }
@@ -9,6 +9,10 @@ @@ -9,6 +9,10 @@
9 9
10 namespace App\Services; 10 namespace App\Services;
11 11
  12 +use App\Helper\Translate;
  13 +use App\Models\Project\ProjectAiSetting;
  14 +use Illuminate\Database\Eloquent\Model;
  15 +
12 class AiBlogService 16 class AiBlogService
13 { 17 {
14 public $url = 'https://ai-extend.ai.cc/'; 18 public $url = 'https://ai-extend.ai.cc/';
@@ -21,6 +25,23 @@ class AiBlogService @@ -21,6 +25,23 @@ class AiBlogService
21 25
22 public $task_id = '';//任务id 26 public $task_id = '';//任务id
23 public $author_id = '';//作者id 27 public $author_id = '';//作者id
  28 +
  29 + public function __construct($project_id = 0)
  30 + {
  31 + if($project_id){
  32 + $projectAiSettingModel = new ProjectAiSetting();
  33 + $aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$project_id]);
  34 + $this->mch_id = $aiSettingInfo['mch_id'];
  35 + $this->key = $aiSettingInfo['key'];
  36 + }
  37 + }
  38 +
  39 + public function setRoute($keyword)
  40 + {
  41 + $this->route = generateRoute(Translate::tran($keyword, 'en'));
  42 + return $this;
  43 + }
  44 +
24 /** 45 /**
25 * @remark :创建项目 46 * @remark :创建项目
26 * @name :createProject 47 * @name :createProject
@@ -191,6 +191,12 @@ return [ @@ -191,6 +191,12 @@ return [
191 'level' => 'debug', 191 'level' => 'debug',
192 'days' => 14, 192 'days' => 14,
193 ], 193 ],
  194 + 'ai_blog' => [
  195 + 'driver' => 'daily',
  196 + 'path' => storage_path('logs/ai_blog/laravel.log'),
  197 + 'level' => 'debug',
  198 + 'days' => 30,
  199 + ],
194 ], 200 ],
195 //操作日志 201 //操作日志
196 'operator_log' =>[ 202 'operator_log' =>[