From d726be7d66d49fad3ab6cad1fa8e72f9545f64e7 Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Fri, 22 Aug 2025 10:23:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/application/ai/config/route.php | 22 +++ Server/application/ai/controller/DouBaoAI.php | 53 +++++++ Server/application/ai/controller/OpenAi.php | 141 ++++++++++++++++++ .../controller/PasswordLoginController.php | 37 +++-- Server/application/common/model/User.php | 2 +- .../cozeai/controller/BaseController.php | 4 +- .../controller/ConversationController.php | 8 +- Server/application/cunkebao/config/route.php | 2 + .../controller/WorkbenchController.php | 41 ++++- .../plan/PosterWeChatMiniProgram.php | 67 +++++++++ .../cunkebao/validate/Workbench.php | 6 +- Server/route/route.php | 3 + 12 files changed, 363 insertions(+), 23 deletions(-) create mode 100644 Server/application/ai/config/route.php create mode 100644 Server/application/ai/controller/DouBaoAI.php create mode 100644 Server/application/ai/controller/OpenAi.php diff --git a/Server/application/ai/config/route.php b/Server/application/ai/config/route.php new file mode 100644 index 00000000..286b7c24 --- /dev/null +++ b/Server/application/ai/config/route.php @@ -0,0 +1,22 @@ +middleware(['jwt']); \ No newline at end of file diff --git a/Server/application/ai/controller/DouBaoAI.php b/Server/application/ai/controller/DouBaoAI.php new file mode 100644 index 00000000..6885c0ee --- /dev/null +++ b/Server/application/ai/controller/DouBaoAI.php @@ -0,0 +1,53 @@ +apiUrl = Env::get('doubaoAi.api_url'); + $this->apiKey = Env::get('doubaoAi.api_key'); + + // 设置请求头 + $this->headers = [ + 'Content-Type: application/json', + 'Authorization: Bearer ' . $this->apiKey + ]; + + if (empty($this->apiKey) || empty($this->apiUrl)) { + return json_encode(['code' => 500, 'msg' => '参数缺失']); + } + } + + + public function text() + { + $this->__init(); + + // 发送请求 + $params = [ + 'model' => 'doubao-1-5-pro-32k-250115', + 'messages' => [ + ['role' => 'system', 'content' => '你是人工智能助手.'], + ['role' => 'user', 'content' => '厦门天气'], + ], + /*'extra_headers' => [ + 'x-is-encrypted' => true + ], + 'temperature' => 1, + 'top_p' => 0.7, + 'max_tokens' => 4096, + 'frequency_penalty' => 0,*/ + ]; + $result = requestCurl($this->apiUrl, $params, 'POST', $this->headers, 'json'); + $result = json_decode($result, true); + return successJson($result); + } +} \ No newline at end of file diff --git a/Server/application/ai/controller/OpenAi.php b/Server/application/ai/controller/OpenAi.php new file mode 100644 index 00000000..3c4f3db4 --- /dev/null +++ b/Server/application/ai/controller/OpenAi.php @@ -0,0 +1,141 @@ +apiUrl = Env::get('openAi.apiUrl'); + $this->apiKey = Env::get('openAi.apiKey'); + + // 设置请求头 + $this->headers = [ + 'Content-Type: application/json', + 'Authorization: Bearer '.$this->apiKey + ]; + } + + + public function text() + { + $this->__init(); + $params = [ + 'model' => 'gpt-3.5-turbo-0125', + 'input' => 'DHA 从孕期到出生到老年都需要,助力大脑发育🧠/减缓脑压力有助记忆/给大脑动力#贝蒂喜藻油DHA 双标认证每粒 150毫克,高含量、高性价比从小吃到老,长期吃更健康 重写这条朋友圈 要求: 1、原本的字数和意思不要修改超过10% 2、出现品牌名或个人名字就去除' + ]; + $result = $this->httpRequest( $this->apiUrl, 'POST', $params,$this->headers); + exit_data($result); + } + + /** + * 示例:调用OpenAI API生成睡前故事 + * 对应curl命令: + * curl "https://api.ai.com/v1/responses" \ + * -H "Content-Type: application/json" \ + * -H "Authorization: Bearer $OPENAI_API_KEY" \ + * -d '{ + * "model": "gpt-5", + * "input": "Write a one-sentence bedtime story about a unicorn." + * }' + */ + public function bedtimeStory() + { + $this->__init(); + + // API请求参数 + $params = [ + 'model' => 'gpt-5', + 'input' => 'Write a one-sentence bedtime story about a unicorn.' + ]; + + // 发送请求到OpenAI API + $url = 'https://api.openai.com/v1/responses'; + $result = $this->httpRequest($url, 'POST', $params, $this->headers); + + // 返回结果 + exit_data($result); + } + + + + + /** + * CURL请求 - 专门用于JSON API请求 + * + * @param $url 请求url地址 + * @param $method 请求方法 get post + * @param null $postfields post数据数组 + * @param array $headers 请求header信息 + * @param int $timeout 超时时间 + * @param bool|false $debug 调试开启 默认false + * @return mixed + */ + protected function httpRequest($url, $method = "GET", $postfields = null, $headers = array(), $timeout = 30, $debug = false) + { + $method = strtoupper($method); + $ci = curl_init(); + + /* Curl settings */ + curl_setopt($ci, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0"); + curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 60); /* 在发起连接前等待的时间,如果设置为0,则无限等待 */ + curl_setopt($ci, CURLOPT_TIMEOUT, $timeout); /* 设置cURL允许执行的最长秒数 */ + curl_setopt($ci, CURLOPT_RETURNTRANSFER, true); + + switch ($method) { + case "POST": + curl_setopt($ci, CURLOPT_POST, true); + if (!empty($postfields)) { + // 对于JSON API,直接将数组转换为JSON字符串 + if (is_array($postfields)) { + $tmpdatastr = json_encode($postfields); + } else { + $tmpdatastr = $postfields; + } + curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr); + } + break; + default: + curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); /* //设置请求方式 */ + break; + } + + $ssl = preg_match('/^https:\/\//i', $url) ? TRUE : FALSE; + curl_setopt($ci, CURLOPT_URL, $url); + if ($ssl) { + curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts + curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在 + } + + if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) { + curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1); + } + curl_setopt($ci, CURLOPT_MAXREDIRS, 2);/*指定最多的HTTP重定向的数量,这个选项是和CURLOPT_FOLLOWLOCATION一起使用的*/ + curl_setopt($ci, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ci, CURLINFO_HEADER_OUT, true); + + $response = curl_exec($ci); + $requestinfo = curl_getinfo($ci); + $http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE); + + if ($debug) { + echo "=====post data======\r\n"; + var_dump($postfields); + echo "=====info===== \r\n"; + print_r($requestinfo); + echo "=====response=====\r\n"; + print_r($response); + } + + curl_close($ci); + return $response; + } + + + +} \ No newline at end of file diff --git a/Server/application/common/controller/PasswordLoginController.php b/Server/application/common/controller/PasswordLoginController.php index f4d12cf0..ce55ba2d 100644 --- a/Server/application/common/controller/PasswordLoginController.php +++ b/Server/application/common/controller/PasswordLoginController.php @@ -57,10 +57,7 @@ class PasswordLoginController extends BaseController throw new \Exception('用户不存在或已禁用', 403); } - $password = md5($password); - - if ($user->passwordMd5 !== $password) { throw new \Exception('账号或密码错误', 403); } @@ -119,8 +116,11 @@ class PasswordLoginController extends BaseController // 生成JWT令牌 $token = JwtUtil::createToken($member, 86400 * 30); $token_expired = time() + 86400 * 30; - - return compact('member', 'token', 'token_expired','deviceTotal'); + $kefuData = [ + 'token' => [], + 'self' => [], + ]; + return compact('member', 'token', 'token_expired','deviceTotal','kefuData'); } /** @@ -131,15 +131,34 @@ class PasswordLoginController extends BaseController public function index() { $params = $this->request->only(['account', 'password', 'typeId']); - try { - $result = $this->dataValidate($params)->doLogin( + $userData = $this->dataValidate($params)->doLogin( $params['account'], $params['password'], $params['typeId'] ); - - return ResponseHelper::success($result, '登录成功'); + //同时登录客服系统 + if (!empty($userData['member']['passwordLocal'])){ + $params = [ + 'grant_type' => 'password', + 'username' => $userData['member']['account'], + 'password' => localDecrypt($userData['member']['passwordLocal']) + ]; + // 调用登录接口获取token + $headerData = ['client:kefu-client']; + $header = setHeader($headerData, '', 'plain'); + $result = requestCurl('https://s2.siyuguanli.com:9991/token', $params, 'POST', $header); + $token = handleApiResponse($result); + $userData['kefuData']['token'] = $token; + if (isset($token['access_token']) && !empty($token['access_token'])) { + $headerData = ['client:kefu-client']; + $header = setHeader($headerData, $token['access_token']); + $result = requestCurl( 'https://s2.siyuguanli.com:9991/api/account/self', [], 'GET', $header,'json'); + $self = handleApiResponse($result); + $userData['kefuData']['self'] = $self; + } + } + return ResponseHelper::success($userData, '登录成功'); } catch (Exception $e) { return ResponseHelper::error($e->getMessage(), $e->getCode()); } diff --git a/Server/application/common/model/User.php b/Server/application/common/model/User.php index 9117d783..9bb3450b 100644 --- a/Server/application/common/model/User.php +++ b/Server/application/common/model/User.php @@ -34,5 +34,5 @@ class User extends Model * 隐藏属性 * @var array */ - protected $hidden = ['passwordMd5', 'passwordLocal', 'deleteTime']; + protected $hidden = ['passwordMd5', 'deleteTime']; } \ No newline at end of file diff --git a/Server/application/cozeai/controller/BaseController.php b/Server/application/cozeai/controller/BaseController.php index 4336ba19..20d1dc70 100644 --- a/Server/application/cozeai/controller/BaseController.php +++ b/Server/application/cozeai/controller/BaseController.php @@ -20,8 +20,8 @@ class BaseController extends Controller parent::__construct(); // 从环境变量获取配置 - $this->apiUrl = Env::get('ai.api_url'); - $this->accessToken = Env::get('ai.token'); + $this->apiUrl = Env::get('cozeAi.api_url'); + $this->accessToken = Env::get('cozeAi.token'); // 设置请求头 $this->headers = [ diff --git a/Server/application/cozeai/controller/ConversationController.php b/Server/application/cozeai/controller/ConversationController.php index 6a04ffe1..59b69b5f 100644 --- a/Server/application/cozeai/controller/ConversationController.php +++ b/Server/application/cozeai/controller/ConversationController.php @@ -101,7 +101,7 @@ class ConversationController extends BaseController public function create($is_internal = false) { try { - $bot_id = Env::get('ai.bot_id'); + $bot_id = Env::get('cozeAi.bot_id'); $userInfo = request()->userInfo; $uid = $userInfo['id']; $companyId = $userInfo['companyId']; @@ -117,7 +117,7 @@ class ConversationController extends BaseController ]; $messages[] = [ 'role' => 'assistant', - 'content' => Env::get('ai.content'), + 'content' => Env::get('cozeAi.content'), 'type' => 'answer', 'content_type' => 'text', ]; @@ -145,7 +145,7 @@ class ConversationController extends BaseController 'chat_id' => $conversation['id'], 'conversation_id' => $conversation['id'], 'bot_id' => $bot_id, - 'content' => Env::get('ai.content'), + 'content' => Env::get('cozeAi.content'), 'content_type' => 'text', 'role' => 'assistant', 'type' => 'answer', @@ -177,7 +177,7 @@ class ConversationController extends BaseController public function createChat() { try { - $bot_id = Env::get('ai.bot_id'); + $bot_id = Env::get('cozeAi.bot_id'); $conversation_id = input('conversation_id',''); $question = input('question',''); diff --git a/Server/application/cunkebao/config/route.php b/Server/application/cunkebao/config/route.php index 5b93d1c0..be31504f 100644 --- a/Server/application/cunkebao/config/route.php +++ b/Server/application/cunkebao/config/route.php @@ -96,6 +96,7 @@ Route::group('v1/', function () { Route::get('device-labels', 'app\cunkebao\controller\WorkbenchController@getDeviceLabels'); // 获取设备微信好友标签统计 Route::get('group-list', 'app\cunkebao\controller\WorkbenchController@getGroupList'); // 获取群列表 Route::get('account-list', 'app\cunkebao\controller\WorkbenchController@getAccountList'); // 获取账号列表 + Route::get('transfer-friends', 'app\cunkebao\controller\WorkbenchController@getTrafficList'); // 获取账号列表 Route::get('getJdSocialMedia', 'app\cunkebao\controller\WorkbenchController@getJdSocialMedia'); // 获取京东联盟导购媒体 Route::get('getJdPromotionSite', 'app\cunkebao\controller\WorkbenchController@getJdPromotionSite'); // 获取京东联盟广告位 @@ -155,6 +156,7 @@ Route::group('v1/frontend', function () { Route::group('business/poster', function () { Route::post('getone', 'app\cunkebao\controller\plan\PosterWeChatMiniProgram@getPosterTaskData'); Route::post('decryptphone', 'app\cunkebao\controller\plan\PosterWeChatMiniProgram@getPhoneNumber'); + Route::post('decryptphones', 'app\cunkebao\controller\plan\PosterWeChatMiniProgram@decryptphones'); }); }); diff --git a/Server/application/cunkebao/controller/WorkbenchController.php b/Server/application/cunkebao/controller/WorkbenchController.php index 599efbfa..4a699e02 100644 --- a/Server/application/cunkebao/controller/WorkbenchController.php +++ b/Server/application/cunkebao/controller/WorkbenchController.php @@ -58,7 +58,7 @@ class WorkbenchController extends Controller $workbench = new Workbench; $workbench->name = $param['name']; $workbench->type = $param['type']; - $workbench->status = 1; + $workbench->status = !empty($param['status']) ? 1 : 0; $workbench->autoStart = !empty($param['autoStart']) ? 1 : 0; $workbench->userId = $userInfo['id']; $workbench->companyId = $userInfo['companyId']; @@ -131,6 +131,8 @@ class WorkbenchController extends Controller $config->maxGroupsPerDay = $param['maxGroupsPerDay']; $config->groupNameTemplate = $param['groupNameTemplate']; $config->groupDescription = $param['groupDescription']; + $config->poolGroups = json_encode($param['poolGroups'] ?? []); + $config->wechatGroups = json_encode($param['wechatGroups'] ?? []); $config->createTime = time(); $config->updateTime = time(); $config->save(); @@ -201,7 +203,7 @@ class WorkbenchController extends Controller $query->field('workbenchId,pushType,startTime,endTime,maxPerDay,pushOrder,isLoop,status,groups,contentLibraries'); }, 'groupCreate' => function($query) { - $query->field('workbenchId,devices,startTime,endTime,groupSizeMin,groupSizeMax,maxGroupsPerDay,groupNameTemplate,groupDescription'); + $query->field('workbenchId,devices,startTime,endTime,groupSizeMin,groupSizeMax,maxGroupsPerDay,groupNameTemplate,groupDescription,poolGroups,wechatGroups'); }, 'user' => function ($query) { $query->field('id,username'); @@ -277,7 +279,7 @@ class WorkbenchController extends Controller $item->config->status = $item->config->status; $item->config->groups = json_decode($item->config->groups, true); $item->config->contentLibraries = json_decode($item->config->contentLibraries, true); - $item->config->lastPushTime = '22222'; + $item->config->lastPushTime = ''; } unset($item->groupPush, $item->group_push); break; @@ -285,6 +287,8 @@ class WorkbenchController extends Controller if (!empty($item->groupCreate)) { $item->config = $item->groupCreate; $item->config->devices = json_decode($item->config->devices, true); + $item->config->poolGroups = json_decode($item->config->poolGroups, true); + $item->config->wechatGroups = json_decode($item->config->wechatGroups, true); } unset($item->groupCreate, $item->group_create); break; @@ -391,7 +395,7 @@ class WorkbenchController extends Controller $query->field('workbenchId,pushType,startTime,endTime,maxPerDay,pushOrder,isLoop,status,groups,contentLibraries'); }, 'groupCreate' => function($query) { - $query->field('workbenchId,devices,startTime,endTime,groupSizeMin,groupSizeMax,maxGroupsPerDay,groupNameTemplate,groupDescription'); + $query->field('workbenchId,devices,startTime,endTime,groupSizeMin,groupSizeMax,maxGroupsPerDay,groupNameTemplate,groupDescription,poolGroups,wechatGroups'); } ]; $workbench = Workbench::where([ @@ -466,6 +470,8 @@ class WorkbenchController extends Controller if (!empty($workbench->groupCreate)) { $workbench->config = $workbench->groupCreate; $workbench->config->deveiceGroups = json_decode($workbench->config->devices, true); + $workbench->config->poolGroups = json_decode($workbench->config->poolGroups, true); + $workbench->config->wechatGroups = json_decode($workbench->config->wechatGroups, true); unset($workbench->groupCreate, $workbench->group_create); } break; @@ -600,6 +606,21 @@ class WorkbenchController extends Controller $workbench->config->accountGroupsOptions = []; } + if (!empty($workbench->config->poolGroups)){ + $poolGroupsOptions = Db::name('traffic_source_package')->alias('tsp') + ->join('traffic_source_package_item tspi','tspi.packageId=tsp.id','left') + ->whereIn('tsp.companyId', [$this->request->userInfo['companyId'],0]) + ->whereIn('tsp.id', $workbench->config->poolGroups) + ->field('tsp.id,tsp.name,tsp.description,tsp.createTime,count(tspi.id) as num') + ->group('tsp.id') + ->select(); + $workbench->config->poolGroupsOptions = $poolGroupsOptions; + }else{ + $workbench->config->poolGroupsOptions = []; + } + + + return json(['code' => 200, 'msg' => '获取成功', 'data' => $workbench]); } @@ -636,6 +657,7 @@ class WorkbenchController extends Controller try { // 更新工作台基本信息 $workbench->name = $param['name']; + $workbench->status = !empty($param['status']) ? 1 : 0; $workbench->autoStart = !empty($param['autoStart']) ? 1 : 0; $workbench->updateTime = time(); $workbench->save(); @@ -720,6 +742,8 @@ class WorkbenchController extends Controller $config->maxGroupsPerDay = $param['maxGroupsPerDay']; $config->groupNameTemplate = $param['groupNameTemplate']; $config->groupDescription = $param['groupDescription']; + $config->poolGroups = json_encode($param['poolGroups'] ?? []); + $config->wechatGroups = json_encode($param['wechatGroups'] ?? []); $config->updateTime = time(); $config->save(); } @@ -859,7 +883,8 @@ class WorkbenchController extends Controller $newConfig->contentTypes = $config->contentTypes; $newConfig->devices = $config->devices; $newConfig->friends = $config->friends; - //$newConfig->targetGroups = $config->targetGroups; + $newConfig->createTime = time(); + $newConfig->updateTime = time(); $newConfig->save(); } break; @@ -876,6 +901,8 @@ class WorkbenchController extends Controller $newConfig->accountType = $config->accountType; $newConfig->devices = $config->devices; $newConfig->contentLibraries = $config->contentLibraries; + $newConfig->createTime = time(); + $newConfig->updateTime = time(); $newConfig->save(); } break; @@ -893,6 +920,8 @@ class WorkbenchController extends Controller $newConfig->status = $config->status; $newConfig->groups = $config->groups; $newConfig->contentLibraries = $config->contentLibraries; + $newConfig->createTime = time(); + $newConfig->updateTime = time(); $newConfig->save(); } break; @@ -909,6 +938,8 @@ class WorkbenchController extends Controller $newConfig->maxGroupsPerDay = $config->maxGroupsPerDay; $newConfig->groupNameTemplate = $config->groupNameTemplate; $newConfig->groupDescription = $config->groupDescription; + $newConfig->poolGroups = $config->poolGroups; + $newConfig->wechatGroups = $config->wechatGroups; $newConfig->createTime = time(); $newConfig->updateTime = time(); $newConfig->save(); diff --git a/Server/application/cunkebao/controller/plan/PosterWeChatMiniProgram.php b/Server/application/cunkebao/controller/plan/PosterWeChatMiniProgram.php index aa5c2b53..b07c7480 100644 --- a/Server/application/cunkebao/controller/plan/PosterWeChatMiniProgram.php +++ b/Server/application/cunkebao/controller/plan/PosterWeChatMiniProgram.php @@ -127,6 +127,73 @@ class PosterWeChatMiniProgram extends Controller } + + + public function decryptphones() { + + $taskId = request()->param('id'); + $phone = request()->param('phone'); + if (!$phone) { + return json([ + 'code' => 400, + 'message' => '手机号不能为空' + ]); + } + + $task = Db::name('customer_acquisition_task')->where('id', $taskId)->find(); + if (!$task) { + return json([ + 'code' => 400, + 'message' => '任务不存在' + ]); + } + + if (!empty($phone)) { + + // TODO 拿到手机号之后的后续操作: + // 1. 先写入 ck_traffic_pool 表 identifier mobile 都是 用 phone字段的值 + $trafficPool = Db::name('traffic_pool')->where('identifier', $phone)->find(); + if (!$trafficPool) { + Db::name('traffic_pool')->insert([ + 'identifier' => $phone, + 'mobile' => $phone, + 'createTime' => time() + ]); + } + + $taskCustomer = Db::name('task_customer')->where('task_id', $taskId)->where('phone', $phone)->find(); + if (!$taskCustomer) { + Db::name('task_customer')->insert([ + 'task_id' => $taskId, + // 'identifier' => $phone, + 'phone' => $phone, + 'source' => $task['name'], + 'createTime' => time(), + 'tags' => json_encode([]), + 'siteTags' => json_encode([]), + ]); + } + // return $phone; + return json([ + 'code' => 200, + 'message' => '获取手机号成功', + 'data' => $phone + ]); + } else { + // return null; + return json([ + 'code' => 400, + 'message' => '手机号失败:' + ]); + } + + // return $result; + + } + + + + // todo 获取海报获客任务的任务/海报数据 -- 表还没设计好,不急 ck_customer_acquisition_task public function getPosterTaskData() { $id = request()->param('id'); diff --git a/Server/application/cunkebao/validate/Workbench.php b/Server/application/cunkebao/validate/Workbench.php index 01fa360c..6796140f 100644 --- a/Server/application/cunkebao/validate/Workbench.php +++ b/Server/application/cunkebao/validate/Workbench.php @@ -48,8 +48,8 @@ class Workbench extends Validate // 自动建群特有参数 'groupNameTemplate' => 'requireIf:type,4|max:50', 'maxGroupsPerDay' => 'requireIf:type,4|number|min:1', - 'groupSizeMin' => 'requireIf:type,4|number|min:1', - 'groupSizeMax' => 'requireIf:type,4|number|min:1', + 'groupSizeMin' => 'requireIf:type,4|number|min:1|max:50', + 'groupSizeMax' => 'requireIf:type,4|number|min:1|max:50', // 流量分发特有参数 'distributeType' => 'requireIf:type,5|in:1,2', 'maxPerDay' => 'requireIf:type,5|number|min:1', @@ -130,9 +130,11 @@ class Workbench extends Validate 'groupSizeMin.requireIf' => '请设置每个群的人数', 'groupSizeMin.number' => '每个群的人数必须为数字', 'groupSizeMin.min' => '每个群的人数必须大于0', + 'groupSizeMin.max' => '每个群的人数最大50人', 'groupSizeMax.requireIf' => '请设置每个群的人数', 'groupSizeMax.number' => '每个群的人数必须为数字', 'groupSizeMax.min' => '每个群的人数必须大于0', + 'groupSizeMax.max' => '每个群的人数最大50人', // 流量分发相关提示 'distributeType.requireIf' => '请选择流量分发类型', 'distributeType.in' => '流量分发类型错误', diff --git a/Server/route/route.php b/Server/route/route.php index 13581e1e..a1adcf1b 100644 --- a/Server/route/route.php +++ b/Server/route/route.php @@ -36,4 +36,7 @@ include __DIR__ . '/../application/superadmin/config/route.php'; // 加载CozeAI模块路由配置 include __DIR__ . '/../application/cozeai/config/route.php'; +// 加载OpenAiAI模块路由配置 +include __DIR__ . '/../application/ai/config/route.php'; + return [];