- Nueva página /chat/comprobantes: tabla paginada de solicitudes_recarga con búsqueda por email/nombre, filtros por estado y canal, botón "Ver chat" - ShowConversaciones: búsqueda también por email del usuario autenticado - ShowConversaciones: soporta ?conv=ID para abrir conversación desde comprobantes - Nav: reemplaza "Menús del Bot" (no funcional) por "Comprobantes" - SolicitudRecarga: relación user() agregada - ChatController: método comprobantes() agregado Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
150 lines
4.2 KiB
PHP
Executable File
150 lines
4.2 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Http\Livewire\Chat;
|
|
|
|
use App\Models\ChatConversation;
|
|
use App\Models\ChatMessage;
|
|
use App\Services\ChatBotEngine;
|
|
use Livewire\Component;
|
|
|
|
class ShowConversaciones extends Component
|
|
{
|
|
public string $busqueda = '';
|
|
public string $filtroEstado = '';
|
|
public ?int $convSelecId = null;
|
|
public string $replyText = '';
|
|
public array $mensajes = [];
|
|
|
|
protected $queryString = ['convSelecId' => ['except' => null, 'as' => 'conv']];
|
|
|
|
public function mount(): void
|
|
{
|
|
if ($this->convSelecId) {
|
|
$this->cargarMensajes();
|
|
}
|
|
}
|
|
|
|
public function selectConv(int $convId): void
|
|
{
|
|
$this->convSelecId = $convId;
|
|
$this->replyText = '';
|
|
$this->cargarMensajes();
|
|
|
|
// Marcar mensajes entrantes como leídos
|
|
ChatMessage::where('conversation_id', $convId)
|
|
->where('tipo', 'usuario')
|
|
->where('leido', false)
|
|
->update(['leido' => true]);
|
|
|
|
ChatConversation::where('id', $convId)
|
|
->update(['mensajes_no_leidos' => 0]);
|
|
}
|
|
|
|
public function cargarMensajes(): void
|
|
{
|
|
if (! $this->convSelecId) {
|
|
$this->mensajes = [];
|
|
return;
|
|
}
|
|
|
|
$this->mensajes = ChatMessage::where('conversation_id', $this->convSelecId)
|
|
->orderBy('id')
|
|
->get()
|
|
->map(fn($m) => [
|
|
'id' => $m->id,
|
|
'tipo' => $m->tipo,
|
|
'contenido' => $m->contenido,
|
|
'created_at' => $m->created_at->format('d/m H:i'),
|
|
])
|
|
->toArray();
|
|
|
|
$this->dispatchBrowserEvent('scroll-admin');
|
|
}
|
|
|
|
public function sendReply(): void
|
|
{
|
|
$this->validate(['replyText' => 'required|string|max:4096']);
|
|
|
|
if (! $this->convSelecId) {
|
|
return;
|
|
}
|
|
|
|
$conv = ChatConversation::with('contact')->find($this->convSelecId);
|
|
if (! $conv) {
|
|
return;
|
|
}
|
|
|
|
ChatMessage::create([
|
|
'conversation_id' => $this->convSelecId,
|
|
'tipo' => 'agente',
|
|
'contenido' => $this->replyText,
|
|
'leido' => true,
|
|
]);
|
|
|
|
$conv->update(['ultimo_mensaje_at' => now()]);
|
|
|
|
// Enviar via Telegram si el canal es telegram
|
|
if ($conv->canal === 'telegram') {
|
|
$engine = new ChatBotEngine();
|
|
$engine->enviarTelegram($conv->contact->canal_id, $this->replyText);
|
|
}
|
|
|
|
$this->replyText = '';
|
|
$this->cargarMensajes();
|
|
}
|
|
|
|
public function cerrarConv(): void
|
|
{
|
|
if (! $this->convSelecId) {
|
|
return;
|
|
}
|
|
|
|
ChatConversation::where('id', $this->convSelecId)
|
|
->update(['estado' => 'cerrada']);
|
|
|
|
$this->cargarMensajes();
|
|
}
|
|
|
|
public function devolverAlBot(): void
|
|
{
|
|
if (! $this->convSelecId) {
|
|
return;
|
|
}
|
|
|
|
ChatConversation::where('id', $this->convSelecId)
|
|
->update(['estado' => 'bot', 'menu_actual_id' => null]);
|
|
}
|
|
|
|
public function tomarControl(): void
|
|
{
|
|
if (! $this->convSelecId) {
|
|
return;
|
|
}
|
|
|
|
ChatConversation::where('id', $this->convSelecId)
|
|
->update(['estado' => 'agente']);
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
$conversaciones = ChatConversation::with('contact')
|
|
->when($this->filtroEstado, fn($q) => $q->where('estado', $this->filtroEstado))
|
|
->when($this->busqueda, function ($q) {
|
|
$q->whereHas('contact', function ($s) {
|
|
$s->where('nombre', 'like', "%{$this->busqueda}%")
|
|
->orWhere('telefono', 'like', "%{$this->busqueda}%")
|
|
->orWhere('canal_id', 'like', "%{$this->busqueda}%")
|
|
->orWhereHas('user', fn($u) => $u->where('email', 'like', "%{$this->busqueda}%"));
|
|
});
|
|
})
|
|
->orderByDesc('ultimo_mensaje_at')
|
|
->get();
|
|
|
|
$convSelec = $this->convSelecId
|
|
? ChatConversation::with('contact')->find($this->convSelecId)
|
|
: null;
|
|
|
|
return view('livewire.chat.show-conversaciones', compact('conversaciones', 'convSelec'));
|
|
}
|
|
}
|