作者 赵彬吉
... ... @@ -69,7 +69,6 @@ class AiBlogAuthorTask extends Command
}
//保存当前项目ai_blog数据
ProjectServer::useProject($info['project_id']);
$data = $result['data'] ?? [];
$this->saveAiBlogAuthor($result['data'] ?? [],$info['project_id']);
DB::disconnect('custom_mysql');
//修改任务状态
... ...
<?php
/**
* @remark :
* @name :AiBlogTask.php
* @author :lyh
* @method :post
* @time :2025/2/14 11:14
*/
namespace App\Console\Commands\AiBlog;
use App\Models\Ai\AiBlog;
use App\Models\Ai\AiBlogAuthor;
use App\Models\Ai\AiBlogList;
use App\Models\Project\ProjectAiSetting;
use App\Models\RouteMap\RouteMap;
use App\Services\AiBlogService;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use App\Models\Project\AiBlogTask as AiBlogTaskModel;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use function Symfony\Component\String\s;
class AiBlogListTask extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'save_ai_blog_list';
/**
* The console command description.
*
* @var string
*/
protected $description = '查询ai_blog是否已经生成';
public function handle(){
$aiBlogTaskModel = new AiBlogTaskModel();
$lists = $aiBlogTaskModel->list(['type'=>3,'status'=>1]);
foreach ($lists as $k => $v){
echo '开始->项目id:' . $v['project_id'] . PHP_EOL . date('Y-m-d H:i:s');
$projectAiSettingModel = new ProjectAiSetting();
$aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$v['project_id']]);
if($aiSettingInfo === false){
continue;
}
$aiBlogService = new AiBlogService();
$aiBlogService->mch_id = $aiSettingInfo['mch_id'];
$aiBlogService->key = $aiSettingInfo['key'];
$page = 1;
$saveData = [];
$result = $aiBlogService->getAiBlogList($page,15);
if(!isset($result['status']) && $result['status'] != 200){
continue;
}
$total_page = $result['data']['total_page'];
//组装数据保存
$saveData[] = [
'route'=>$page,
'text'=>$result['data']['section'],
];
while ($total_page > $page){
$page++;
$result = $aiBlogService->getAiBlogList($page,15);
if(isset($result['status']) && $result['status'] == 200){
$saveData[] = [
'route'=>$page,
'text'=>$result['data']['section'],
];
}
}
//保存当前项目ai_blog数据
ProjectServer::useProject($v['project_id']);
$aiBlogListModel = new AiBlogList();
if(!empty($saveData)){
$aiBlogListModel->truncate();
$aiBlogListModel->insertAll($saveData);
}
DB::disconnect('custom_mysql');
//修改任务状态
$aiBlogTaskModel->edit(['status'=>2],['id'=>$v['id']]);
echo '结束->->项目id:' . $v['project_id'] . PHP_EOL . date('Y-m-d H:i:s');
}
return true;
}
}
... ...
... ... @@ -12,6 +12,7 @@ namespace App\Console\Commands\AiBlog;
use App\Models\Ai\AiBlog;
use App\Models\Ai\AiBlogAuthor;
use App\Models\Project\ProjectAiSetting;
use App\Models\RouteMap\RouteMap;
use App\Services\AiBlogService;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
... ... @@ -63,7 +64,17 @@ class AiBlogTask extends Command
//保存当前项目ai_blog数据
ProjectServer::useProject($info['project_id']);
$aiBlogModel = new AiBlog();
$aiBlogModel->edit(['new_title'=>$result['data']['title'], 'image'=>$result['data']['thumb'], 'text'=>$result['data']['section'], 'author_id'=>$result['data']['author_id'], 'status'=>2], ['task_id'=>$info['task_id']]);
$aiBlogInfo = $aiBlogModel->read(['task_id'=>$info['task_id']],['id']);
if($aiBlogInfo === false){
$aiBlogTaskModel->edit(['status'=>2],['id'=>$info['id']]);
continue;
}
//拿到返回的路由查看是否重复
$route = RouteMap::setRoute($result['data']['url'], RouteMap::SOURCE_AI_BLOG, $aiBlogInfo['id'], $info['project_id']);
if($route != $result['data']['url']){
$aiBlogService->updateDetail(['route'=>$this->param['route']]);
}
$aiBlogModel->edit(['new_title'=>$result['data']['title'], 'image'=>$result['data']['thumb'], 'text'=>$result['data']['section'], 'author_id'=>$result['data']['author_id'], 'route'=>$route ,'status'=>2], ['task_id'=>$info['task_id']]);
$this->updateAiBlogAuthor($aiSettingInfo,$result['data']['author_id']);
DB::disconnect('custom_mysql');
//修改任务状态
... ...
... ... @@ -58,6 +58,10 @@ class SyncInquiryRelay extends Command
if (isset($result['status']) && $result['status'] == 200) {
$data = $result['data'] ?? [];
foreach ($data as $item) {
if (substr($item['phone'], 0, 3) == '+86') {
//+86区号过滤
continue;
}
$this->saveDate($item, $item['source_type']);
}
}
... ...
... ... @@ -16,6 +16,8 @@ use App\Models\Product\CategoryRelated;
use App\Models\Product\Detail;
use App\Models\Product\Product;
use App\Models\RouteMap\RouteMap;
use App\Models\Visit\Visit;
use App\Models\Visit\VisitItem;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
... ... @@ -50,7 +52,7 @@ class DownloadProject extends Command
{
$product = new Product();
$filed = ['id', 'project_id', 'title' ,'thumb' , 'route' ,'intro','content',
'category_id', 'status'];
'category_id', 'status','seo_mate'];
$this->order = 'sort';
$lists = $product->list(['status'=>1],'id',$filed);
if(!empty($lists)){
... ... @@ -106,6 +108,39 @@ class DownloadProject extends Command
}
return $data;
}
// public function exportData($data){
// // 创建一个新的 Excel 电子表格实例
// $spreadsheet = new Spreadsheet();
// $sheet = $spreadsheet->getActiveSheet();
// // 添加表头
// $sheet->setCellValue('A1', '浏览时间');
// $sheet->setCellValue('B1', '访客来源');
// $sheet->setCellValue('C1', '访客入路页面');
// $sheet->setCellValue('D1', '终端');
// $sheet->setCellValue('E1', '国家ip');
// $sheet->setCellValue('F1', '深度访问页数');
// $rowCount = 2;
// foreach ($data as $v) {
// $sheet->setCellValue('A' . $rowCount, $v['created_at']);
// $sheet->setCellValue('B' . $rowCount, $v['referrer_url']);
// $sheet->setCellValue('C' . $rowCount, $v['url']);
// $sheet->setCellValue('D' . $rowCount, $v['device_text']);
// $sheet->setCellValue('E' . $rowCount, $v['ip']);
// $sheet->setCellValue('F' . $rowCount, $v['depth']);
// $rowCount++;
// }
// // 创建一个新的 Excel Writer 对象
// $writer = new Xlsx($spreadsheet);
// $filename = time().'.xlsx';
// // 设置导出文件的保存路径和文件名
// $filePath = public_path('upload/excel/'.$filename);
// // 导出 Excel 文件
// $writer->save($filePath);
// echo date('Y-m-d H:i:s') . 'file_link:'.url('upload/excel/'.$filename) . PHP_EOL;
// // 返回导出文件的响应
// return ['file_link'=>url('upload/excel/'.$filename)];
// }
public function exportData($data){
// 创建一个新的 Excel 电子表格实例
$spreadsheet = new Spreadsheet();
... ... @@ -118,6 +153,7 @@ class DownloadProject extends Command
$sheet->setCellValue('E1', '产品分类');
$sheet->setCellValue('F1', '产品状态');
$sheet->setCellValue('G1', '产品主图');
$sheet->setCellValue('H1', '产品TDK');
$rowCount = 2;
foreach ($data as $v) {
$sheet->setCellValue('A' . $rowCount, $v['title']);
... ... @@ -127,6 +163,7 @@ class DownloadProject extends Command
$sheet->setCellValue('E' . $rowCount, $v['category_id_text']);
$sheet->setCellValue('F' . $rowCount, '发布中');
$sheet->setCellValue('G' . $rowCount, $v['images']);
$sheet->setCellValue('H' . $rowCount, $v['seo_mate']);
$rowCount++;
}
// 创建一个新的 Excel Writer 对象
... ... @@ -140,4 +177,27 @@ class DownloadProject extends Command
// 返回导出文件的响应
return ['file_link'=>url('upload/excel/'.$filename)];
}
// public function downloadItem($filed = ['id','depth','created_at','referrer_url','url','device_port','country','ip']){
// $visitModel = new Visit();
// $page = 1;
// $pageSize = 3000;
// $lists = $visitModel->lists(['updated_date'=>['between',['2025-02-01','2025-02-31']]],$page,$pageSize,'id',$filed);
// foreach ($lists as $v){
// $customer_visit_id[] = $v['id'];
// }
// $itemModel = new VisitItem();
// $itemList = $itemModel->list(['customer_visit_id'=>['in',$customer_visit_id]],['customer_visit_id','url']);
// foreach ($lists as $key => $value){
// $sub = [];
// foreach ($itemList as $sonValue){
// if($value['id'] == $sonValue['customer_visit_id']){
// $sub[] = $sonValue;
// }
// }
// $value['sub'] = $sub;
// $lists[$key] = $value;
// }
// return $lists;
// }
}
... ...
... ... @@ -8,6 +8,7 @@ use App\Http\Logic\Bside\Ai\AiBlogLogic;
use App\Http\Requests\Bside\Ai\AiBlogRequest;
use App\Models\Ai\AiBlog;
use App\Models\Ai\AiBlogAuthor;
use App\Models\Ai\AiBlogList;
use App\Services\AiBlogService;
use App\Services\ProjectServer;
use Illuminate\Support\Facades\DB;
... ... @@ -15,19 +16,6 @@ use Illuminate\Support\Facades\DB;
class AiBlogController extends BaseController
{
/**
* @remark :Ai博客发布
* @name :save
* @author :lyh
* @method :post
* @time :2023/7/5 14:33
*/
public function save(AiBlogRequest $aiBlogRequest,AiBlogLogic $aiBlogLogic){
$aiBlogRequest->validated();
$aiBlogLogic->blogSave();
$this->response('success');
}
/**
* @remark :获取详情
* @name :getInfo
* @author :lyh
... ... @@ -46,21 +34,21 @@ class AiBlogController extends BaseController
}
/**
* @remark :删除
* @name :delete
* @remark :获取详情数据
* @name :getAuthorInfo
* @author :lyh
* @method :post
* @time :2025/2/20 18:19
* @time :2025/2/21 13:54
*/
public function delete(AiBlogLogic $aiBlogLogic)
{
public function getAuthorInfo(AiBlogAuthor $aiBlogAuthor){
$this->request->validate([
'ids'=>['required', new Ids()]
'id'=>['required'],
],[
'ids.required' => 'ID不能为空'
'id.required' => '主键不能为空',
]);
$aiBlogLogic->blogDelete();
$this->response('success');
$info = $aiBlogAuthor->read($this->map);
$info['image'] = getImageUrl($info['image']);
$this->response('success',Code::SUCCESS,$info);
}
/**
... ... @@ -92,11 +80,9 @@ class AiBlogController extends BaseController
$this->request->validate([
'keyword'=>['required'],
'type'=>['required'],
'route'=>['required']
],[
'keyword.required' => '关键字不能为空',
'type.required' => '场景不能为空',
'route.required' => '路由不能为空',
]);
//获取当前项目的ai_blog设置
$result = $aiBlogLogic->sendTask();
... ... @@ -117,37 +103,80 @@ class AiBlogController extends BaseController
}
/**
* @remark :获取详情数据
* @name :getAuthorInfo
* @remark :Ai博客发布
* @name :save
* @author :lyh
* @method :post
* @time :2023/7/5 14:33
*/
public function save(AiBlogRequest $aiBlogRequest,AiBlogLogic $aiBlogLogic){
$aiBlogRequest->validated();
$aiBlogLogic->blogSave();
$this->response('success');
}
/**
* @remark :编辑作者详情数据
* @name :saveBlogAuthor
* @author :lyh
* @method :post
* @time :2025/2/21 13:54
*/
public function getAuthorInfo(AiBlogAuthor $aiBlogAuthor){
public function saveBlogAuthor(AiBlogLogic $aiBlogLogic){
$this->request->validate([
'id'=>['required'],
],[
'id.required' => '主键不能为空',
]);
$info = $aiBlogAuthor->read($this->map);
$info['image'] = getImageUrl($info['image']);
$info = $aiBlogLogic->saveBlogAuthor();
$this->response('success',Code::SUCCESS,$info);
}
/**
* @remark :获取详情数据
* @name :getAuthorInfo
* @remark :删除
* @name :delete
* @author :lyh
* @method :post
* @time :2025/2/21 13:54
* @time :2025/2/20 18:19
*/
public function saveBlogAuthor(AiBlogLogic $aiBlogLogic){
public function delete(AiBlogLogic $aiBlogLogic)
{
$this->request->validate([
'ids'=>['required', new Ids()]
],[
'ids.required' => 'ID不能为空'
]);
$aiBlogLogic->blogDelete();
$this->response('success');
}
/**
* @remark :获取列表页数据
* @name :getAiBlogList
* @author :lyh
* @method :post
* @time :2025/2/21 16:22
*/
public function getAiBlogList(AiBlogList $aiBlogList){
$lists = $aiBlogList->lists($this->map,$this->page,$this->row,'id',['id','route','created_at','updated_at']);
$this->response('success',Code::SUCCESS,$lists);
}
/**
* @remark :获取列表页数据详情
* @name :getAiBlogListInfo
* @author :lyh
* @method :post
* @time :2025/2/21 16:26
*/
public function getAiBlogListInfo(AiBlogList $aiBlogList){
$this->request->validate([
'id'=>['required'],
],[
'id.required' => '主键不能为空',
]);
$info = $aiBlogLogic->saveBlogAuthor();
$info = $aiBlogList->read($this->map);
$this->response('success',Code::SUCCESS,$info);
}
}
... ...
... ... @@ -216,7 +216,7 @@ class ProjectLogic extends BaseLogic
if($aiSettingInfo === false){
$aiBlogService = new AiBlogService();
$result = $aiBlogService->createProject($title,$languageInfo['short'],$projectInfo['company']);
if($result['status'] == 200){
if(isset($result['status']) && $result['status'] == 200){
//查看当前项目是否已有记录
$resData = [
'project_id'=>$project_id,
... ... @@ -232,15 +232,7 @@ class ProjectLogic extends BaseLogic
$aiBlogService = new AiBlogService();
$aiBlogService->mch_id = $aiSettingInfo['mch_id'];
$aiBlogService->key = $aiSettingInfo['key'];
$result = $aiBlogService->updatedProject($title,$languageInfo['short']);
if($result['status'] == 200){
$resData = [
'mch_id'=>$result['data']['mch_id'],
'key'=>$result['data']['key'],
];
$aiSettingModel = new ProjectAiSetting();
$aiSettingModel->edit($resData,['project_id'=>$project_id]);
}
$aiBlogService->updatedProject($title,$languageInfo['short']);
}
}
return true;
... ...
... ... @@ -5,6 +5,7 @@ namespace App\Http\Logic\Bside\Ai;
use App\Helper\Translate;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\Ai\AiBlog;
use App\Models\Ai\AiBlogAuthor;
use App\Models\Project\AiBlogTask;
use App\Models\Project\Project;
use App\Models\Project\ProjectAiSetting;
... ... @@ -21,6 +22,22 @@ class AiBlogLogic extends BaseLogic
}
/**
* @remark :获取配置信息
* @name :getProjectAiSetting
* @author :lyh
* @method :post
* @time :2025/2/21 14:51
*/
public function getProjectAiSetting(){
$projectAiSettingModel = new ProjectAiSetting();
$aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$this->user['project_id']]);
if($aiSettingInfo === false){
$this->fail('请先联系管理员开启Ai博客');
}
return $aiSettingInfo;
}
/**
* @remark :ai发布博客
* @name :blogSave
* @author :lyh
... ... @@ -38,9 +55,7 @@ class AiBlogLogic extends BaseLogic
$aiBlogService = new AiBlogService();
$aiBlogService->mch_id = $aiSettingInfo['mch_id'];
$aiBlogService->key = $aiSettingInfo['key'];
$aiBlogService->route = $this->param['route'];
$aiBlogService->author_id = $this->param['author_id'];
$aiBlogService->updateDetail($this->param['title'],$this->param['image']);
$aiBlogService->updateDetail(['title'=>$this->param['title'],'thumb'=>$this->param['image'],'route'=>$this->param['route'],'author_id'=>$this->param['author_id']]);
}catch (\Exception $e){
$this->fail('保存失败,请联系管理员');
}
... ... @@ -48,22 +63,6 @@ class AiBlogLogic extends BaseLogic
}
/**
* @remark :获取配置信息
* @name :getProjectAiSetting
* @author :lyh
* @method :post
* @time :2025/2/21 14:51
*/
public function getProjectAiSetting(){
$projectAiSettingModel = new ProjectAiSetting();
$aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$this->user['project_id']]);
if($aiSettingInfo === false){
$this->fail('请先联系管理员开启Ai博客');
}
return $aiSettingInfo;
}
/**
* @remark :编辑作者
* @name :saveAuthor
* @author :lyh
... ... @@ -72,11 +71,14 @@ class AiBlogLogic extends BaseLogic
*/
public function saveBlogAuthor(){
try {
$aiAuthorModel = new AiBlogAuthor();
if(!empty($this->param['image'])){
$this->param['image'] = str_replace_url($this->param['image']);
}
$this->param['route'] = RouteMap::setRoute($this->param['route'], RouteMap::SOURCE_AI_BLOG_AUTHOR, $this->param['id'], $this->user['project_id']);
$this->model->edit($this->param,['id'=>$this->param['id']]);
$aiAuthorModel->edit($this->param,['id'=>$this->param['id']]);
$aiBlogService = new AiBlogService();
$aiBlogService->updateAuthorInfo(['author_id'=>$this->param['author_id'],'title'=>$this->param['title'],'picture'=>$this->param['image'],'description'=>$this->param['description']]);
}catch (\Exception $e){
$this->fail('保存失败,请联系管理员');
}
... ... @@ -89,6 +91,8 @@ class AiBlogLogic extends BaseLogic
* @author :lyh
* @method :post
* @time :2025/2/14 10:28
* @detail :type=2/生成文章 type=3/更新列表页记录
* @detail :status=1/待执行
*/
public function sendTask(){
$aiSettingInfo = $this->getProjectAiSetting();
... ... @@ -99,33 +103,20 @@ class AiBlogLogic extends BaseLogic
$result = $aiBlogService->createTask($this->param['keyword'],$this->param['type']);
if($result['status'] == 200){
$aiBlogTaskModel = new AiBlogTask();
$aiBlogTaskModel->addReturnId(['project_id'=>$this->user['project_id'],'task_id'=>$result['data']['task_id'],'status'=>$result['data']['status']]);
$aiBlogTaskModel->addReturnId(['project_id'=>$this->user['project_id'],'type'=>2,'task_id'=>$result['data']['task_id'],'status'=>1]);
//增加一条更新列表页的记录
$aiThreeInfo = $aiBlogTaskModel->read(['project_id'=>$this->user['project_id'],'type'=>3,'status'=>1]);
if($aiThreeInfo === false){
$aiBlogTaskModel->addReturnId(['project_id'=>$this->user['project_id'],'type'=>3,'status'=>1]);
}
$aiBlogModel = new AiBlog();
$aiBlogId = $aiBlogModel->addReturnId(['keyword'=>$this->param['keyword'], 'status'=>$result['data']['status'], 'task_id'=>$result['data']['task_id'],'project_id'=>$this->user['project_id'],
$aiBlogModel->addReturnId(['keyword'=>$this->param['keyword'], 'status'=>1, 'task_id'=>$result['data']['task_id'],'project_id'=>$this->user['project_id'],
]);
$route = RouteMap::setRoute($aiBlogService->route, RouteMap::SOURCE_AI_BLOG, $aiBlogId, $this->user['project_id']);
$aiBlogModel->edit(['route'=>$route],['id'=>$aiBlogId]);
}
return $this->success();
}
/**
* @remark :创建作者
* @name :createAuthor
* @author :lyh
* @method :post
* @time :2025/2/20 10:46
*/
public function createAuthor(){
$aiSettingInfo = $this->getProjectAiSetting();
$aiBlogService = new AiBlogService();
$aiBlogService->mch_id = $aiSettingInfo['mch_id'];
$aiBlogService->key = $aiSettingInfo['key'];
$result = $aiBlogService->createAuthor();
return $this->success($result);
}
/**
* @remark :删除
* @name :blogDelete
* @author :lyh
... ... @@ -144,4 +135,5 @@ class AiBlogLogic extends BaseLogic
}
return $this->success();
}
}
... ...
<?php
/**
* @remark :
* @name :AiBlogList.php
* @author :lyh
* @method :post
* @time :2025/2/21 15:57
*/
namespace App\Models\Ai;
use App\Models\Base;
class AiBlogList extends Base
{
protected $table = 'gl_ai_blog_list';
//连接数据库
protected $connection = 'custom_mysql';
}
... ...
... ... @@ -20,7 +20,6 @@ class AiBlogService
public $route = '';//回调地址
public $task_id = '';//任务id
public $author_id = '';//作者id
/**
* @remark :创建项目
... ... @@ -189,17 +188,46 @@ class AiBlogService
* @author :lyh
* @method :post
* @time :2025/2/21 14:38
* @param :title , thumb , route , task_id
*/
public function updateDetail($title,$image){
public function updateDetail($param){
$request_url = $this->url.'api/result/save';
$param = [
'mch_id'=>$this->mch_id,
'author_id'=>$this->author_id,
'route'=>$this->route,
'author_id'=>$this->author_id,
'title'=>$title,
'thumb'=>$image,
];
$param['mch_id'] = $this->mch_id;
$this->sign = $this->generateSign($param,$this->key);
$param['sign'] = $this->sign;
$result = http_post($request_url,json_encode($param,true));
return $result;
}
/**
* @remark :获取列表页数据
* @name :getAiBlogList
* @author :lyh
* @method :post
* @time :2025/2/21 15:51
*/
public function getAiBlogList($page,$page_size){
$request_url = $this->url.'api/result/list';
$param['mch_id'] = $this->mch_id;
$param['page'] = $page;
$param['page_size'] = $page_size;
$this->sign = $this->generateSign($param,$this->key);
$param['sign'] = $this->sign;
$result = http_post($request_url,json_encode($param,true));
return $result;
}
/**
* @remark :修改作者信息
* @name :updateAuthorInfo
* @author :lyh
* @method :post
* @time :2025/2/21 16:00
* @param :author_id ,title , picture, description
*/
public function updateAuthorInfo($param){
$request_url = $this->url.'api/author/update';
$param['mch_id'] = $this->mch_id;
$this->sign = $this->generateSign($param,$this->key);
$param['sign'] = $this->sign;
$result = http_post($request_url,json_encode($param,true));
... ...
... ... @@ -161,6 +161,8 @@ Route::middleware(['bloginauth'])->group(function () {
Route::any('/blog/getAuthorInfo', [\App\Http\Controllers\Bside\Ai\AiBlogController::class, 'getAuthorInfo'])->name('ai_blog_getAuthorInfo');
Route::any('/blog/saveBlogAuthor', [\App\Http\Controllers\Bside\Ai\AiBlogController::class, 'saveBlogAuthor'])->name('ai_blog_saveBlogAuthor');
Route::any('/blog/getInfo', [\App\Http\Controllers\Bside\Ai\AiBlogController::class, 'getInfo'])->name('ai_blog_getInfo');
Route::any('/blog/getAiBlogList', [\App\Http\Controllers\Bside\Ai\AiBlogController::class, 'getAiBlogList'])->name('ai_blog_getAiBlogList');
Route::any('/blog/getAiBlogListInfo', [\App\Http\Controllers\Bside\Ai\AiBlogController::class, 'getAiBlogListInfo'])->name('ai_blog_getAiBlogListInfo');
Route::any('/product/', [\App\Http\Controllers\Bside\Ai\AiProductController::class, 'save'])->name('ai_product_save');
Route::any('/product/productList', [\App\Http\Controllers\Bside\Ai\AiProductController::class, 'productList'])->name('ai_product_productList');
Route::any('/product/productCateList', [\App\Http\Controllers\Bside\Ai\AiProductController::class, 'productCateList'])->name('ai_product_productCateList');
... ...