58 lines
1.7 KiB
PHP
58 lines
1.7 KiB
PHP
<?php
|
||
|
||
namespace Leantime\Domain\Ai\Controllers;
|
||
|
||
use Illuminate\Http\Request;
|
||
use Leantime\Domain\Ai\Services\AiChat;
|
||
use Symfony\Component\HttpFoundation\Response;
|
||
|
||
/**
|
||
* 界面内 AI 聊天 JSON API(原生 Laravel 控制器)。
|
||
* 前端右下角悬浮窗发 {messages},后端代理 DeepSeek/千问并执行工具调用。
|
||
*/
|
||
class ChatApi
|
||
{
|
||
public function __construct(
|
||
private AiChat $aiChat,
|
||
) {}
|
||
|
||
/**
|
||
* POST /ai/chat
|
||
*/
|
||
public function chat(Request $request): Response
|
||
{
|
||
$messages = $request->input('messages', []);
|
||
|
||
if (! is_array($messages) || empty($messages)) {
|
||
return response()->json(['status' => 'error', 'message' => 'messages 不能为空'], 400);
|
||
}
|
||
|
||
// 只保留 role/content 字段,防止注入多余字段
|
||
$clean = [];
|
||
foreach ($messages as $m) {
|
||
if (is_array($m) && isset($m['role'])) {
|
||
$clean[] = [
|
||
'role' => (string) $m['role'],
|
||
'content' => (string) ($m['content'] ?? ''),
|
||
];
|
||
}
|
||
}
|
||
|
||
$result = $this->aiChat->chat($clean);
|
||
|
||
return $result['success']
|
||
? response()->json(['status' => 'success', 'content' => $result['content']])
|
||
: response()->json(['status' => 'error', 'message' => $result['error'] ?? 'AI 调用失败'], 500);
|
||
}
|
||
|
||
/**
|
||
* GET /ai/config —— 返回当前 AI 配置(脱敏,apiKey 只显示前 6 位 + 掩码)。
|
||
*/
|
||
public function config(): Response
|
||
{
|
||
$cfg = $this->aiChat->publicConfig();
|
||
|
||
return response()->json(['status' => 'success', 'data' => $cfg]);
|
||
}
|
||
}
|