197 lines
6.2 KiB
PHP
197 lines
6.2 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Http\Controllers\Sales;
|
||
|
|
|
||
|
|
use App\Http\Controllers\Controller;
|
||
|
|
use App\Services\Sales\AiInterviewService;
|
||
|
|
use Illuminate\Http\JsonResponse;
|
||
|
|
use Illuminate\Http\Request;
|
||
|
|
use Illuminate\View\View;
|
||
|
|
|
||
|
|
class AiInterviewController extends Controller
|
||
|
|
{
|
||
|
|
public function __construct(
|
||
|
|
private AiInterviewService $aiInterviewService
|
||
|
|
) {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* AI 인터뷰 메인 페이지
|
||
|
|
*/
|
||
|
|
public function index(Request $request): View|\Illuminate\Http\Response
|
||
|
|
{
|
||
|
|
if ($request->header('HX-Request')) {
|
||
|
|
return response('', 200)->header('HX-Redirect', route('sales.interviews.ai.index'));
|
||
|
|
}
|
||
|
|
|
||
|
|
return view('sales.interviews.ai-interview');
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* AI 인터뷰 세션 시작
|
||
|
|
*/
|
||
|
|
public function startSession(Request $request): JsonResponse
|
||
|
|
{
|
||
|
|
$validated = $request->validate([
|
||
|
|
'project_id' => 'required|integer|exists:interview_projects,id',
|
||
|
|
'domain' => 'required|string|max:50',
|
||
|
|
'interviewee_name' => 'nullable|string|max:100',
|
||
|
|
'interviewee_company' => 'nullable|string|max:100',
|
||
|
|
]);
|
||
|
|
|
||
|
|
try {
|
||
|
|
$result = $this->aiInterviewService->startAiSession(
|
||
|
|
$validated['project_id'],
|
||
|
|
$validated['domain'],
|
||
|
|
$validated['interviewee_name'] ?? null,
|
||
|
|
$validated['interviewee_company'] ?? null,
|
||
|
|
);
|
||
|
|
|
||
|
|
return response()->json(['success' => true, 'data' => $result]);
|
||
|
|
} catch (\Exception $e) {
|
||
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* AI에게 메시지 전송
|
||
|
|
*/
|
||
|
|
public function sendMessage(Request $request): JsonResponse
|
||
|
|
{
|
||
|
|
$validated = $request->validate([
|
||
|
|
'session_id' => 'required|integer|exists:interview_sessions,id',
|
||
|
|
'message' => 'required|string|max:10000',
|
||
|
|
'domain' => 'nullable|string|max:50',
|
||
|
|
]);
|
||
|
|
|
||
|
|
try {
|
||
|
|
$result = $this->aiInterviewService->sendMessage(
|
||
|
|
$validated['session_id'],
|
||
|
|
$validated['message'],
|
||
|
|
$validated['domain'] ?? null,
|
||
|
|
);
|
||
|
|
|
||
|
|
return response()->json(['success' => true, 'data' => $result]);
|
||
|
|
} catch (\Exception $e) {
|
||
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 대화 히스토리 조회
|
||
|
|
*/
|
||
|
|
public function getHistory(int $sessionId): JsonResponse
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
$history = $this->aiInterviewService->getConversationHistory($sessionId);
|
||
|
|
|
||
|
|
return response()->json(['success' => true, 'data' => $history]);
|
||
|
|
} catch (\Exception $e) {
|
||
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 진행률 분석
|
||
|
|
*/
|
||
|
|
public function analyzeProgress(int $sessionId): JsonResponse
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
$progress = $this->aiInterviewService->analyzeProgress($sessionId);
|
||
|
|
|
||
|
|
return response()->json(['success' => true, 'data' => $progress]);
|
||
|
|
} catch (\Exception $e) {
|
||
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 지식 자동 추출
|
||
|
|
*/
|
||
|
|
public function extractKnowledge(int $sessionId): JsonResponse
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
$knowledge = $this->aiInterviewService->extractKnowledge($sessionId);
|
||
|
|
|
||
|
|
return response()->json(['success' => true, 'data' => $knowledge]);
|
||
|
|
} catch (\Exception $e) {
|
||
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 음성 파일 업로드 + STT 변환
|
||
|
|
*/
|
||
|
|
public function uploadVoice(Request $request): JsonResponse
|
||
|
|
{
|
||
|
|
$request->validate([
|
||
|
|
'session_id' => 'required|integer|exists:interview_sessions,id',
|
||
|
|
'audio' => 'required|file|mimes:webm,wav,mp3,ogg,m4a|max:51200',
|
||
|
|
]);
|
||
|
|
|
||
|
|
try {
|
||
|
|
$result = $this->aiInterviewService->processVoiceUpload(
|
||
|
|
$request->input('session_id'),
|
||
|
|
$request->file('audio'),
|
||
|
|
);
|
||
|
|
|
||
|
|
return response()->json(['success' => true, 'data' => $result]);
|
||
|
|
} catch (\Exception $e) {
|
||
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 파일 업로드 + AI 분석
|
||
|
|
*/
|
||
|
|
public function uploadFile(Request $request): JsonResponse
|
||
|
|
{
|
||
|
|
$request->validate([
|
||
|
|
'project_id' => 'required|integer|exists:interview_projects,id',
|
||
|
|
'session_id' => 'nullable|integer|exists:interview_sessions,id',
|
||
|
|
'file' => 'required|file|max:51200',
|
||
|
|
'file_type' => 'nullable|string|in:excel_template,pdf_quote,sample_bom,price_list,photo,other',
|
||
|
|
]);
|
||
|
|
|
||
|
|
try {
|
||
|
|
$result = $this->aiInterviewService->processFileUpload(
|
||
|
|
$request->input('project_id'),
|
||
|
|
$request->file('file'),
|
||
|
|
$request->input('file_type', 'other'),
|
||
|
|
$request->input('session_id'),
|
||
|
|
);
|
||
|
|
|
||
|
|
return response()->json(['success' => true, 'data' => $result]);
|
||
|
|
} catch (\Exception $e) {
|
||
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 프로젝트별 도메인 목록 + 진행 현황
|
||
|
|
*/
|
||
|
|
public function getDomains(int $projectId): JsonResponse
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
$domains = $this->aiInterviewService->getProjectDomains($projectId);
|
||
|
|
|
||
|
|
return response()->json(['success' => true, 'data' => $domains]);
|
||
|
|
} catch (\Exception $e) {
|
||
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 프로젝트 목록 조회
|
||
|
|
*/
|
||
|
|
public function getProjects(): JsonResponse
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
$projects = $this->aiInterviewService->getProjects();
|
||
|
|
|
||
|
|
return response()->json(['success' => true, 'data' => $projects]);
|
||
|
|
} catch (\Exception $e) {
|
||
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|