Files
cunkebao_v3/Server/application/cunkebao/controller/AiAssistantController.php
Manus AI a3bda0ccac fix: API获客 sceneId=11 列表500与小宝AI网关联通
Query whereIn 合并 legacy 场景;karuoAi 120s 超时,避免误降级 doubao 欠费。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 16:08:15 +08:00

174 lines
5.6 KiB
PHP

<?php
namespace app\cunkebao\controller;
use app\cunkebao\service\AiAssistantService;
use library\ResponseHelper;
use think\facade\Log;
/**
* 存客宝 · AI 智能助手
* 自然语言配置获客计划 / 查询设备微信 / 算力扣费
*/
class AiAssistantController extends BaseController
{
protected function service(): AiAssistantService
{
return new AiAssistantService($this->getUserInfo());
}
/**
* GET /v1/ai-assistant/chat-history
*/
public function chatHistory()
{
try {
$sessionId = trim((string)$this->request->param('sessionId', ''));
if ($sessionId === '') {
$sessionId = $this->service()->newSessionId();
}
$list = $this->service()->getChatHistory($sessionId);
return ResponseHelper::success([
'sessionId' => $sessionId,
'list' => $list,
]);
} catch (\Exception $e) {
$code = (int)$e->getCode();
if ($code === 401) {
return ResponseHelper::unauthorized($e->getMessage());
}
return ResponseHelper::error($e->getMessage());
}
}
/**
* POST /v1/ai-assistant/send-message
*/
public function sendMessage()
{
try {
$message = trim((string)$this->request->param('message', ''));
$sessionId = trim((string)$this->request->param('sessionId', ''));
$result = $this->service()->sendMessage($sessionId, $message);
if (!empty($result['needRecharge'])) {
return ResponseHelper::error($result['msg'] ?? '算力余额不足', 402, [
'needRecharge' => true,
'rechargePath' => $result['rechargePath'] ?? '/recharge?tab=buy',
]);
}
return ResponseHelper::success($result, 'ok');
} catch (\Exception $e) {
Log::error('AiAssistant sendMessage: ' . $e->getMessage());
$code = (int)$e->getCode();
if ($code === 401) {
return ResponseHelper::unauthorized($e->getMessage());
}
return ResponseHelper::error($e->getMessage());
}
}
/**
* POST /v1/ai-assistant/send-message-stream
* SSE: session | delta | done | error
*/
public function sendMessageStream()
{
$message = trim((string)$this->request->param('message', ''));
$sessionId = trim((string)$this->request->param('sessionId', ''));
header('Content-Type: text/event-stream; charset=utf-8');
header('Cache-Control: no-cache, no-transform');
header('Connection: keep-alive');
header('X-Accel-Buffering: no');
if (function_exists('apache_setenv')) {
@apache_setenv('no-gzip', '1');
}
@ini_set('zlib.output_compression', '0');
@ini_set('output_buffering', 'off');
@ini_set('implicit_flush', '1');
while (ob_get_level() > 0) {
ob_end_flush();
}
$emit = function (string $event, array $data) {
echo 'event: ' . $event . "\n";
echo 'data: ' . json_encode($data, JSON_UNESCAPED_UNICODE) . "\n\n";
if (ob_get_level() > 0) {
ob_flush();
}
flush();
};
try {
$this->service()->sendMessageStream($sessionId, $message, $emit);
} catch (\Exception $e) {
Log::error('AiAssistant sendMessageStream: ' . $e->getMessage());
$code = (int)$e->getCode();
if ($code === 401) {
$emit('error', ['code' => 401, 'msg' => $e->getMessage()]);
} else {
$emit('error', ['code' => 500, 'msg' => $e->getMessage()]);
}
}
exit;
}
/**
* POST /v1/ai-assistant/confirm-actions
*/
public function confirmActions()
{
try {
$sessionId = trim((string)$this->request->param('sessionId', ''));
$messageId = trim((string)$this->request->param('messageId', ''));
$actionIds = $this->request->param('actionIds/a', []);
if (!is_array($actionIds)) {
$actionIds = [];
}
$result = $this->service()->confirmActions($sessionId, $messageId, $actionIds);
if (!empty($result['needRecharge'])) {
return ResponseHelper::error($result['msg'] ?? '算力余额不足', 402, [
'needRecharge' => true,
'rechargePath' => $result['rechargePath'] ?? '/recharge?tab=buy',
]);
}
return ResponseHelper::success($result, '配置已应用');
} catch (\Exception $e) {
return ResponseHelper::error($e->getMessage());
}
}
/**
* GET /v1/ai-assistant/analysis-report
*/
public function analysisReport()
{
try {
$data = $this->service()->buildAnalysisReport();
return ResponseHelper::success($data);
} catch (\Exception $e) {
return ResponseHelper::error($e->getMessage());
}
}
/**
* GET /v1/ai-assistant/tools
*/
public function listTools()
{
try {
$tools = (new \app\cunkebao\service\AiAssistantToolService($this->getUserInfo()))->toolCatalog();
return ResponseHelper::success([
'tools' => $tools,
'apiCatalog' => \app\cunkebao\service\AiAssistantApiCatalog::all(),
]);
} catch (\Exception $e) {
return ResponseHelper::error($e->getMessage());
}
}
}