作者 李宇航

合并分支 'master-server' 到 'master'

Master server



查看合并请求 !1106
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :AiBlogTask.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/2/14 11:14
  8 + */
  9 +
  10 +namespace App\Console\Commands\AiBlog;
  11 +
  12 +use App\Models\Ai\AiBlog;
  13 +use App\Models\Project\ProjectAiSetting;
  14 +use App\Services\AiBlogService;
  15 +use App\Services\ProjectServer;
  16 +use Illuminate\Console\Command;
  17 +use App\Models\Project\AiBlogTask as AiBlogTaskModel;
  18 +use Illuminate\Support\Facades\Cache;
  19 +use Illuminate\Support\Facades\DB;
  20 +use function Symfony\Component\String\s;
  21 +
  22 +class AiBlogTask extends Command
  23 +{
  24 + /**
  25 + * The name and signature of the console command.
  26 + *
  27 + * @var string
  28 + */
  29 + protected $signature = 'save_ai_blog';
  30 +
  31 + /**
  32 + * The console command description.
  33 + *
  34 + * @var string
  35 + */
  36 + protected $description = '查询ai_blog是否已经生成';
  37 +
  38 + public function handle(){
  39 + $aiBlogTaskModel = new AiBlogTaskModel();
  40 + while (true){
  41 + $info = $aiBlogTaskModel->where('status',1)->orderBy('id','asc')->first();
  42 + if($info === false){
  43 + sleep(10);
  44 + }
  45 + $info = $info->toArray();
  46 + echo '开始->任务id:' . $info['task_id'] . PHP_EOL . date('Y-m-d H:i:s');
  47 + //获取配置
  48 + $aiSettingInfo = $this->getSetting($info['project_id']);
  49 + $aiBlogService = new AiBlogService();
  50 + $aiBlogService->mch_id = $aiSettingInfo['mch_id'];
  51 + $aiBlogService->key = $aiSettingInfo['key'];
  52 + $aiBlogService->task_id = $info['task_id'];
  53 + $result = $aiBlogService->getDetail();
  54 + if($result['status'] != 200){
  55 + sleep(5);
  56 + continue;
  57 + }
  58 + //修改任务状态
  59 + $aiBlogTaskModel->edit(['status'=>2],['id'=>$info['id']]);
  60 + //保存当前项目ai_blog数据
  61 + ProjectServer::useProject($info['project_id']);
  62 + $aiBlogModel = new AiBlog();
  63 + $aiBlogModel->edit(['new_title'=>$result['data']['title'] ?? '','text'=>$result['data']['text'] ?? '','status'=>2],['task_id'=>$info['task_id']]);
  64 + DB::disconnect('custom_mysql');
  65 + echo '结束->任务id:' . $info['task_id'] . PHP_EOL . date('Y-m-d H:i:s');
  66 + }
  67 + return true;
  68 + }
  69 +
  70 + /**
  71 + * @remark :获取项目配置
  72 + * @name :getSetting
  73 + * @author :lyh
  74 + * @method :post
  75 + * @time :2025/2/14 11:27
  76 + */
  77 + public function getSetting($project_id){
  78 + $ai_cache = Cache::get('ai_blog_'.$project_id);
  79 + if($ai_cache){
  80 + return $ai_cache;
  81 + }
  82 + $projectAiSettingModel = new ProjectAiSetting();
  83 + $aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$project_id]);
  84 + Cache::put('ai_blog_'.$project_id,$aiSettingInfo,3600);
  85 + return $aiSettingInfo;
  86 + }
  87 +}
@@ -2,9 +2,14 @@ @@ -2,9 +2,14 @@
2 2
3 namespace App\Http\Controllers\Bside\Ai; 3 namespace App\Http\Controllers\Bside\Ai;
4 4
  5 +use App\Enums\Common\Code;
5 use App\Http\Controllers\Bside\BaseController; 6 use App\Http\Controllers\Bside\BaseController;
6 use App\Http\Logic\Bside\Ai\AiBlogLogic; 7 use App\Http\Logic\Bside\Ai\AiBlogLogic;
7 use App\Http\Requests\Bside\Ai\AiBlogRequest; 8 use App\Http\Requests\Bside\Ai\AiBlogRequest;
  9 +use App\Models\Ai\AiBlog;
  10 +use App\Services\AiBlogService;
  11 +use App\Services\ProjectServer;
  12 +use Illuminate\Support\Facades\DB;
8 13
9 class AiBlogController extends BaseController 14 class AiBlogController extends BaseController
10 { 15 {
@@ -20,4 +25,24 @@ class AiBlogController extends BaseController @@ -20,4 +25,24 @@ class AiBlogController extends BaseController
20 $aiBlogLogic->blogSave(); 25 $aiBlogLogic->blogSave();
21 $this->response('success'); 26 $this->response('success');
22 } 27 }
  28 +
  29 + /**
  30 + * @remark :发布任务
  31 + * @name :sendTask
  32 + * @author :lyh
  33 + * @method :post
  34 + * @time :2025/2/14 10:25
  35 + */
  36 + public function sendTask(AiBlogLogic $aiBlogLogic){
  37 + $this->request->validate([
  38 + 'keyword'=>['required'],
  39 + 'type'=>['required']
  40 + ],[
  41 + 'keyword.required' => '关键字不能为空',
  42 + 'type.required' => '场景不能为空',
  43 + ]);
  44 + //获取当前项目的ai_blog设置
  45 + $result = $aiBlogLogic->sendTask();
  46 + $this->response('success',Code::SUCCESS,$result);
  47 + }
23 } 48 }
@@ -662,7 +662,7 @@ class ProductController extends BaseController @@ -662,7 +662,7 @@ class ProductController extends BaseController
662 'product_id.required' => 'product_id不能为空', 662 'product_id.required' => 'product_id不能为空',
663 ]); 663 ]);
664 $productInfo = $product->read(['id' => $this->param['product_id']]); 664 $productInfo = $product->read(['id' => $this->param['product_id']]);
665 - if (empty($productInfo)) { 665 + if ($productInfo == false) {
666 $this->fail('请选择有效产品信息!'); 666 $this->fail('请选择有效产品信息!');
667 } 667 }
668 $productInfo = $this->handleParam($productInfo); 668 $productInfo = $this->handleParam($productInfo);
@@ -12,6 +12,7 @@ namespace App\Http\Controllers\Bside; @@ -12,6 +12,7 @@ namespace App\Http\Controllers\Bside;
12 use App\Enums\Common\Code; 12 use App\Enums\Common\Code;
13 use App\Helper\PayStripeApi; 13 use App\Helper\PayStripeApi;
14 use App\Http\Logic\Bside\News\NewsLogic; 14 use App\Http\Logic\Bside\News\NewsLogic;
  15 +use App\Models\Ai\AiBlog;
15 use App\Models\Channel\Channel; 16 use App\Models\Channel\Channel;
16 use App\Models\CustomModule\CustomModuleCategory; 17 use App\Models\CustomModule\CustomModuleCategory;
17 use App\Models\CustomModule\CustomModuleContent; 18 use App\Models\CustomModule\CustomModuleContent;
@@ -21,24 +22,38 @@ use App\Models\ExtentModule\ExtensionModuleValue; @@ -21,24 +22,38 @@ use App\Models\ExtentModule\ExtensionModuleValue;
21 use App\Models\Manage\ManageHr; 22 use App\Models\Manage\ManageHr;
22 use App\Models\Project\CountAllProject as AllProject; 23 use App\Models\Project\CountAllProject as AllProject;
23 use App\Models\Project\Project; 24 use App\Models\Project\Project;
  25 +use App\Models\Project\ProjectAiSetting;
24 use App\Models\RouteMap\RouteMap; 26 use App\Models\RouteMap\RouteMap;
  27 +use App\Services\AiBlogService;
25 use App\Services\ProjectServer; 28 use App\Services\ProjectServer;
26 use Illuminate\Support\Facades\DB; 29 use Illuminate\Support\Facades\DB;
27 30
28 class TestController extends BaseController 31 class TestController extends BaseController
29 { 32 {
30 /** 33 /**
31 - * @remark :非6.0拉取数据  
32 - * @name :NoSixProject 34 + * @remark :创建项目
  35 + * @name :createProject
33 * @author :lyh 36 * @author :lyh
34 * @method :post 37 * @method :post
35 - * @time :2024/11/11 14:51 38 + * @time :2025/2/13 16:34
36 */ 39 */
37 public function ceshi(){ 40 public function ceshi(){
38 - $pay = new PayStripeApi();  
39 - $data = $pay->createPaymentIntent(5000,'cny');  
40 - $this->response('success',Code::SUCCESS,$data); 41 + $aiBlogService = new AiBlogService();
  42 + $aiBlogService->mch_id = '100008';
  43 + $aiBlogService->key = '8a9c925bdcca';
  44 + $result = $aiBlogService->createTask('apple');
  45 + if($result['status'] == 200){
  46 + $param = [
  47 + 'keywords'=>'apple',
  48 + 'status'=>$result['data']['status'],
  49 + 'task_id'=>$result['data']['task_id'],
  50 + 'project_id'=>1,
  51 + ];
  52 + ProjectServer::useProject(1);
  53 + $aiBlogModel = new AiBlog();
  54 + $aiBlogModel->add($param);
  55 + DB::disconnect('custom_mysql');
  56 + }
  57 + $this->response('success',Code::SUCCESS,$param);
41 } 58 }
42 -  
43 -  
44 } 59 }
@@ -30,6 +30,7 @@ use App\Models\Project\InquiryFilterConfig; @@ -30,6 +30,7 @@ use App\Models\Project\InquiryFilterConfig;
30 use App\Models\Project\MinorLanguages; 30 use App\Models\Project\MinorLanguages;
31 use App\Models\Project\Payment; 31 use App\Models\Project\Payment;
32 use App\Models\Project\Project; 32 use App\Models\Project\Project;
  33 +use App\Models\Project\ProjectAiSetting;
33 use App\Models\Project\ProjectKeyword; 34 use App\Models\Project\ProjectKeyword;
34 use App\Models\Project\ProjectRenew; 35 use App\Models\Project\ProjectRenew;
35 use App\Models\Project\WebTrafficConfig; 36 use App\Models\Project\WebTrafficConfig;
@@ -43,6 +44,7 @@ use App\Models\User\ProjectMenu; @@ -43,6 +44,7 @@ use App\Models\User\ProjectMenu;
43 use App\Models\User\ProjectRole; 44 use App\Models\User\ProjectRole;
44 use App\Models\User\User as UserModel; 45 use App\Models\User\User as UserModel;
45 use App\Models\WebSetting\WebLanguage; 46 use App\Models\WebSetting\WebLanguage;
  47 +use App\Services\AiBlogService;
46 use App\Services\ProjectServer; 48 use App\Services\ProjectServer;
47 use App\Services\SyncService; 49 use App\Services\SyncService;
48 use App\Utils\LogUtils; 50 use App\Utils\LogUtils;
@@ -158,6 +160,8 @@ class ProjectLogic extends BaseLogic @@ -158,6 +160,8 @@ class ProjectLogic extends BaseLogic
158 $this->setServers($this->param['serve_id'],$this->param['id']); 160 $this->setServers($this->param['serve_id'],$this->param['id']);
159 //保存项目信息 161 //保存项目信息
160 $this->saveProject($this->param); 162 $this->saveProject($this->param);
  163 + //ai_blog
  164 + $this->setAiBlog($this->param['id'],$this->param['main_lang_id'],$this->param['is_ai_blog'],$this->param['title']);
161 //保存建站部署信息 165 //保存建站部署信息
162 $this->saveProjectDeployBuild($this->param['deploy_build']); 166 $this->saveProjectDeployBuild($this->param['deploy_build']);
163 //保存付费信息 167 //保存付费信息
@@ -184,6 +188,59 @@ class ProjectLogic extends BaseLogic @@ -184,6 +188,59 @@ class ProjectLogic extends BaseLogic
184 } 188 }
185 189
186 /** 190 /**
  191 + * @remark :开启AI博客后
  192 + * @name :setAiBlog
  193 + * @author :lyh
  194 + * @method :post
  195 + * @time :2025/2/13 16:02
  196 + */
  197 + public function setAiBlog($project_id,$main_lang_id,$is_ai_blog,$title){
  198 + if(empty($main_lang_id) || empty($is_ai_blog)){
  199 + return true;
  200 + }
  201 + $projectModel = new Project();
  202 + $projectInfo = $projectModel->read(['id'=>$project_id],['is_ai_blog','main_lang_id']);
  203 + //获取项目主语种
  204 + $languageModel = new WebLanguage();
  205 + $languageInfo = $languageModel->read(['id'=>$main_lang_id],['short']);
  206 + if($languageInfo == false){
  207 + return true;
  208 + }
  209 + $aiSettingModel = new ProjectAiSetting();
  210 + $aiSettingInfo = $aiSettingModel->read(['project_id'=>$project_id]);
  211 + if($aiSettingInfo === false){
  212 + $aiBlogService = new AiBlogService();
  213 + $result = $aiBlogService->createProject($title,$languageInfo['short'],$projectInfo['company']);
  214 + if($result['status'] == 200){
  215 + //查看当前项目是否已有记录
  216 + $resData = [
  217 + 'project_id'=>$project_id,
  218 + 'mch_id'=>$result['data']['mch_id'],
  219 + 'key'=>$result['data']['key'],
  220 + ];
  221 + $aiSettingModel->add($resData);
  222 + }
  223 + }else{
  224 + //有信息更新
  225 + if(($projectInfo['title'] != $title) || ($projectInfo['main_lang_id'] != $main_lang_id)){
  226 + $aiBlogService = new AiBlogService();
  227 + $aiBlogService->mch_id = $aiSettingInfo['mch_id'];
  228 + $aiBlogService->key = $aiSettingInfo['key'];
  229 + $result = $aiBlogService->updatedProject($title,$languageInfo['short']);
  230 + if($result['status'] == 200){
  231 + $resData = [
  232 + 'mch_id'=>$result['data']['mch_id'],
  233 + 'key'=>$result['data']['key'],
  234 + ];
  235 + $aiSettingModel = new ProjectAiSetting();
  236 + $aiSettingModel->edit($resData,['project_id'=>$project_id]);
  237 + }
  238 + }
  239 + }
  240 + return true;
  241 + }
  242 +
  243 + /**
187 * @remark :选择服务器后双向绑定 244 * @remark :选择服务器后双向绑定
188 * @name :setServers 245 * @name :setServers
189 * @author :lyh 246 * @author :lyh
@@ -4,6 +4,10 @@ namespace App\Http\Logic\Bside\Ai; @@ -4,6 +4,10 @@ namespace App\Http\Logic\Bside\Ai;
4 4
5 use App\Http\Logic\Bside\BaseLogic; 5 use App\Http\Logic\Bside\BaseLogic;
6 use App\Models\Ai\AiBlog; 6 use App\Models\Ai\AiBlog;
  7 +use App\Models\Project\AiBlogTask;
  8 +use App\Models\Project\Project;
  9 +use App\Models\Project\ProjectAiSetting;
  10 +use App\Services\AiBlogService;
7 11
8 class AiBlogLogic extends BaseLogic 12 class AiBlogLogic extends BaseLogic
9 { 13 {
@@ -29,4 +33,35 @@ class AiBlogLogic extends BaseLogic @@ -29,4 +33,35 @@ class AiBlogLogic extends BaseLogic
29 } 33 }
30 return $this->success(); 34 return $this->success();
31 } 35 }
  36 +
  37 + /**
  38 + * @remark :发布任务
  39 + * @name :sendTask
  40 + * @author :lyh
  41 + * @method :post
  42 + * @time :2025/2/14 10:28
  43 + */
  44 + public function sendTask(){
  45 + $projectAiSettingModel = new ProjectAiSetting();
  46 + $aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$this->user['project_id']]);
  47 + if($aiSettingInfo === false){
  48 + $this->fail('请先联系管理员开启Ai博客');
  49 + }
  50 + $aiBlogService = new AiBlogService();
  51 + $aiBlogService->mch_id = $aiSettingInfo['mch_id'];
  52 + $aiBlogService->key = $aiSettingInfo['key'];
  53 + $result = $aiBlogService->createTask($this->param['keyword'],$this->param['type']);
  54 + if($result['status'] == 200){
  55 + try {
  56 + $aiBlogTaskModel = new AiBlogTask();
  57 + $aiBlogTaskModel->addReturnId(['project_id'=>$this->user['project_id'],'task_id'=>$result['data']['task_id'],'status'=>$result['data']['status']]);
  58 + $aiBlogModel = new AiBlog();
  59 + $aiBlogModel->addReturnId(['keyword'=>$this->param['keyword'], 'status'=>$result['data']['status'], 'task_id'=>$result['data']['task_id'],'project_id'=>$this->user['project_id'],
  60 + ]);
  61 + }catch (\Exception $e){
  62 + $this->fail('请求ai_blog失败,请联系管理员');
  63 + }
  64 + }
  65 + return $this->success();
  66 + }
32 } 67 }
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :AiBlogTask.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/2/14 11:03
  8 + */
  9 +
  10 +namespace App\Models\Project;
  11 +
  12 +use App\Models\Base;
  13 +
  14 +class AiBlogTask extends Base
  15 +{
  16 + protected $table = 'gl_ai_blog_task';
  17 +}
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :ProjectAiSetting.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/2/13 16:53
  8 + */
  9 +
  10 +namespace App\Models\Project;
  11 +
  12 +use App\Models\Base;
  13 +
  14 +/**
  15 + * @remark :项目ai_blog设置
  16 + * @name :ProjectAiSetting
  17 + * @author :lyh
  18 + * @method :post
  19 + * @time :2025/2/13 16:53
  20 + */
  21 +class ProjectAiSetting extends Base
  22 +{
  23 + protected $table = 'gl_project_ai_setting';
  24 +}
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :AiBlogService.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/2/13 14:15
  8 + */
  9 +
  10 +namespace App\Services;
  11 +
  12 +class AiBlogService
  13 +{
  14 + public $url = 'https://ai-extend.ai.cc/';
  15 +
  16 + public $mch_id = 1;//默认配置
  17 + public $sign = '';//签名
  18 + public $key = 'b3e4c722b821';//默认key
  19 +
  20 + public $webhook = 'https://develop.globalso.com/api/ai_webhook';//回调地址
  21 +
  22 + public $task_id = '';//任务id
  23 + /**
  24 + * @remark :创建项目
  25 + * @name :createProject
  26 + * @author :lyh
  27 + * @method :post
  28 + * @time :2025/2/13 14:28
  29 + */
  30 + public function createProject($project_name,$language = 'en',$profile){
  31 + $request_url = $this->url.'api/project/create';
  32 + $param = [
  33 + 'mch_id'=>$this->mch_id,
  34 + 'title'=>$project_name,
  35 + 'language'=>$language,
  36 + 'profile'=>$profile
  37 + ];
  38 + $this->sign = $this->generateSign($param,$this->key);
  39 + $param['sign'] = $this->sign;
  40 + $result = http_post($request_url,json_encode($param,true));
  41 + return $result;
  42 + }
  43 +
  44 + /**
  45 + * @remark :更新项目
  46 + * @name :updatedProject
  47 + * @author :lyh
  48 + * @method :post
  49 + * @time :2025/2/13 14:35
  50 + */
  51 + public function updatedProject($project_name,$language = 'en'){
  52 + $request_url = $this->url.'api/project/save';
  53 + $param = [
  54 + 'mch_id'=>$this->mch_id,
  55 + 'title'=>$project_name,
  56 + 'language'=>$language
  57 + ];
  58 + $this->sign = $this->generateSign($param,$this->key);
  59 + $param['sign'] = $this->sign;
  60 + $result = http_post($request_url,json_encode($param,true));
  61 + return $result;
  62 + }
  63 +
  64 + /**
  65 + * @remark :创建任务
  66 + * @name :createTask
  67 + * @author :lyh
  68 + * @method :post
  69 + * @time :2025/2/13 14:39
  70 + * @param :type=(1作者2文章) keyword=关键词 subtype=blog url=回调url
  71 + */
  72 + public function createTask($keyword,$type = 1,$subtype = 'Blog',$template_id = 1){
  73 + $request_url = $this->url.'api/task/create';
  74 + $param = [
  75 + 'mch_id'=>$this->mch_id,
  76 + 'keyword'=>$keyword,
  77 + 'type'=>$type,
  78 + 'subtype'=>$subtype,
  79 + 'url'=>$this->webhook,
  80 + 'template_id'=>$template_id
  81 + ];
  82 + $this->sign = $this->generateSign($param,$this->key);
  83 + $param['sign'] = $this->sign;
  84 + $result = http_post($request_url,json_encode($param,true));
  85 + return $result;
  86 + }
  87 +
  88 + /**
  89 + * @remark :创建作者
  90 + * @name :createAuthor
  91 + * @author :lyh
  92 + * @method :post
  93 + * @time :2025/2/13 14:43
  94 + */
  95 + public function createAuthor(){
  96 + $request_url = $this->url.'api/author/create';
  97 + $param = [
  98 + 'mch_id'=>$this->mch_id,
  99 + 'sign'=>$this->sign,
  100 + ];
  101 + $result = http_post($request_url,json_encode($param,true));
  102 + return $result;
  103 + }
  104 +
  105 + /**
  106 + * @remark :计算签名
  107 + * @name :generateSign
  108 + * @author :lyh
  109 + * @method :post
  110 + * @time :2025/2/13 15:07
  111 + */
  112 + public function generateSign($params, $key)
  113 + {
  114 + // 去除数组中所有值为空的项
  115 + array_filter($params);
  116 + // 按照key值的ASCII码从小到大排序
  117 + ksort($params);
  118 + // 生成URL的查询字符串
  119 + $string = http_build_query($params);
  120 + // 生成签名
  121 + $sign = md5($string . $key);
  122 + // 转换成大写
  123 + $sign = strtoupper($sign);
  124 + return $sign;
  125 + }
  126 +
  127 + /**
  128 + * @remark :获取文章详情
  129 + * @name :getDetail
  130 + * @author :lyh
  131 + * @method :post
  132 + * @time :2025/2/14 11:23
  133 + */
  134 + public function getDetail(){
  135 + $request_url = $this->url.'api/result/detail';
  136 + $param = [
  137 + 'mch_id'=>$this->mch_id,
  138 + 'task_id'=>$this->task_id,
  139 + ];
  140 + $this->sign = $this->generateSign($param,$this->key);
  141 + $param['sign'] = $this->sign;
  142 + $result = http_post($request_url,json_encode($param,true));
  143 + return $result;
  144 + }
  145 +}
@@ -154,6 +154,7 @@ Route::middleware(['bloginauth'])->group(function () { @@ -154,6 +154,7 @@ Route::middleware(['bloginauth'])->group(function () {
154 //ai 154 //ai
155 Route::any('/news/', [\App\Http\Controllers\Bside\Ai\AiNewsController::class, 'save'])->name('ai_news_save'); 155 Route::any('/news/', [\App\Http\Controllers\Bside\Ai\AiNewsController::class, 'save'])->name('ai_news_save');
156 Route::any('/blog/', [\App\Http\Controllers\Bside\Ai\AiBlogController::class, 'save'])->name('ai_blog_save'); 156 Route::any('/blog/', [\App\Http\Controllers\Bside\Ai\AiBlogController::class, 'save'])->name('ai_blog_save');
  157 + Route::any('/blog/sendTask', [\App\Http\Controllers\Bside\Ai\AiBlogController::class, 'sendTask'])->name('ai_blog_sendTask');
157 Route::any('/product/', [\App\Http\Controllers\Bside\Ai\AiProductController::class, 'save'])->name('ai_product_save'); 158 Route::any('/product/', [\App\Http\Controllers\Bside\Ai\AiProductController::class, 'save'])->name('ai_product_save');
158 Route::any('/product/productList', [\App\Http\Controllers\Bside\Ai\AiProductController::class, 'productList'])->name('ai_product_productList'); 159 Route::any('/product/productList', [\App\Http\Controllers\Bside\Ai\AiProductController::class, 'productList'])->name('ai_product_productList');
159 Route::any('/product/productCateList', [\App\Http\Controllers\Bside\Ai\AiProductController::class, 'productCateList'])->name('ai_product_productCateList'); 160 Route::any('/product/productCateList', [\App\Http\Controllers\Bside\Ai\AiProductController::class, 'productCateList'])->name('ai_product_productCateList');