118 lines
3.7 KiB
PHP
118 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Category;
|
|
use App\Models\ChatFeedback;
|
|
use App\Models\ChatLog;
|
|
use App\Models\KnowledgeItem;
|
|
use App\Services\KnowledgeBase\AuditService;
|
|
use App\Services\KnowledgeBase\IngestionService;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\View\View;
|
|
|
|
class ChatFeedbackController extends Controller
|
|
{
|
|
public function __construct(
|
|
private readonly AuditService $auditService,
|
|
private readonly IngestionService $ingestionService,
|
|
) {}
|
|
|
|
/**
|
|
* Senarai log chat dengan filter dan status feedback.
|
|
*/
|
|
public function index(Request $request): View
|
|
{
|
|
$query = ChatLog::with(['session', 'category', 'feedback'])
|
|
->latest();
|
|
|
|
if ($request->filled('has_answer')) {
|
|
$query->where('has_answer', (bool) $request->has_answer);
|
|
}
|
|
|
|
if ($request->filled('is_flagged')) {
|
|
$query->where('is_flagged', true);
|
|
}
|
|
|
|
if ($request->filled('category_id')) {
|
|
$query->where('category_id', $request->category_id);
|
|
}
|
|
|
|
if ($request->filled('rating')) {
|
|
$query->whereHas('feedback', fn($q) => $q->where('rating', $request->rating));
|
|
}
|
|
|
|
$logs = $query->paginate(20)->withQueryString();
|
|
$categories = Category::active()->ordered()->get();
|
|
|
|
return view('admin.chat-feedback.index', compact('logs', 'categories'));
|
|
}
|
|
|
|
/**
|
|
* Semak satu log chat dengan butiran penuh.
|
|
*/
|
|
public function show(ChatLog $chatLog): View
|
|
{
|
|
$chatLog->load(['session', 'category', 'feedback.convertedFaq']);
|
|
|
|
return view('admin.chat-feedback.show', compact('chatLog'));
|
|
}
|
|
|
|
/**
|
|
* Convert soalan yang tidak dijawab dengan baik kepada FAQ rasmi.
|
|
*/
|
|
public function convertToFaq(Request $request, ChatLog $chatLog): RedirectResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'category_id' => ['required', 'exists:categories,id'],
|
|
'title' => ['required', 'string', 'max:500'],
|
|
'content' => ['required', 'string', 'max:10000'],
|
|
]);
|
|
|
|
$knowledgeItem = KnowledgeItem::create([
|
|
'category_id' => $validated['category_id'],
|
|
'item_type' => KnowledgeItem::TYPE_FAQ,
|
|
'title' => $validated['title'],
|
|
'content' => $validated['content'],
|
|
'is_active' => true,
|
|
'is_public' => true,
|
|
'created_by' => auth()->id(),
|
|
'updated_by' => auth()->id(),
|
|
]);
|
|
|
|
// Kemaskini feedback jika ada
|
|
if ($feedback = $chatLog->feedback) {
|
|
$feedback->update([
|
|
'converted_to_faq' => true,
|
|
'converted_faq_id' => $knowledgeItem->id,
|
|
'reviewed_by' => auth()->id(),
|
|
'reviewed_at' => now(),
|
|
]);
|
|
}
|
|
|
|
// Flag log chat sebagai dah diselesaikan
|
|
$chatLog->update(['is_flagged' => false]);
|
|
|
|
$this->auditService->faqConvertedFromFeedback($feedback, $knowledgeItem);
|
|
|
|
// Embed knowledge item baru
|
|
\App\Jobs\ReindexKnowledgeItemJob::dispatch($knowledgeItem->id);
|
|
|
|
return redirect()
|
|
->route('admin.knowledge-items.show', $knowledgeItem)
|
|
->with('success', "FAQ baru '{$knowledgeItem->title}' berjaya dicipta dari log chat.");
|
|
}
|
|
|
|
/**
|
|
* Toggle flag pada log chat untuk tanda perlu semakan.
|
|
*/
|
|
public function toggleFlag(ChatLog $chatLog): RedirectResponse
|
|
{
|
|
$chatLog->update(['is_flagged' => !$chatLog->is_flagged]);
|
|
|
|
return back()->with('success', $chatLog->is_flagged ? 'Log ditanda untuk semakan.' : 'Flag dibuang.');
|
|
}
|
|
}
|