Integração com o banco de dados
This commit is contained in:
@@ -16,6 +16,23 @@ export interface AudioGenerationResponse {
|
||||
message: string; // Texto que foi convertido em áudio
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface para um áudio armazenado no banco de dados
|
||||
*/
|
||||
export interface AudioRecord {
|
||||
id: string;
|
||||
user_email: string;
|
||||
estabelecimento_id: number;
|
||||
input_text: string;
|
||||
model: string;
|
||||
voice: VoiceType;
|
||||
audio_url: string;
|
||||
duration_seconds: number | null;
|
||||
file_size: number;
|
||||
cost_usd: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface para os dados necessários para geração de áudio
|
||||
*/
|
||||
@@ -73,6 +90,8 @@ export const VOICE_OPTIONS = {
|
||||
*/
|
||||
class AudioGenerationService {
|
||||
private readonly AUDIO_GENERATION_ENDPOINT = '/webhook/codex/gerar_audio';
|
||||
private readonly GET_AUDIOS_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/get_gerar_audios';
|
||||
private readonly DELETE_AUDIO_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/delete_gerar_audio';
|
||||
|
||||
/**
|
||||
* Gera um arquivo de áudio a partir de texto
|
||||
@@ -192,6 +211,149 @@ class AudioGenerationService {
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Lista áudios do banco de dados com paginação
|
||||
*
|
||||
* @param userEmail - Email do usuário
|
||||
* @param page - Número da página (padrão: 1)
|
||||
* @param perPage - Quantidade de itens por página (padrão: 10)
|
||||
* @returns Promise com o array de áudios
|
||||
*/
|
||||
async getAudios(
|
||||
userEmail?: string,
|
||||
page: number = 1,
|
||||
perPage: number = 10
|
||||
): Promise<AudioRecord[]> {
|
||||
// Usa valores do GlobalFunctions se não forem fornecidos
|
||||
const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
|
||||
|
||||
if (!email) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Email do usuário não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Buscando áudios:', {
|
||||
userEmail: email,
|
||||
page,
|
||||
perPage,
|
||||
});
|
||||
|
||||
try {
|
||||
// Faz a requisição GET com parâmetros na URL e query
|
||||
const response = await apiService.get<AudioRecord[]>(
|
||||
`${this.GET_AUDIOS_ENDPOINT}/${email}`,
|
||||
{
|
||||
params: {
|
||||
page: page.toString(),
|
||||
per_page: perPage.toString(),
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
console.log('Resposta completa da API:', response);
|
||||
console.log('response.data:', response.data);
|
||||
console.log('É array?:', Array.isArray(response.data));
|
||||
|
||||
// A API retorna diretamente o array de áudios
|
||||
// Garante que sempre retorna um array
|
||||
if (Array.isArray(response.data)) {
|
||||
return response.data;
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
// Se a resposta for um objeto com uma propriedade 'audios' ou similar
|
||||
console.warn('API retornou objeto em vez de array:', response.data);
|
||||
|
||||
// Tenta encontrar o array dentro do objeto
|
||||
if (Array.isArray((response.data as any).audios)) {
|
||||
return (response.data as any).audios;
|
||||
} else if (Array.isArray((response.data as any).data)) {
|
||||
return (response.data as any).data;
|
||||
}
|
||||
}
|
||||
|
||||
// Se não conseguir extrair array, retorna vazio
|
||||
console.warn('Não foi possível extrair array de áudios da resposta');
|
||||
return [];
|
||||
} catch (error: any) {
|
||||
console.error('Erro ao buscar áudios:', error);
|
||||
|
||||
throw {
|
||||
success: false,
|
||||
message: error.message || 'Erro ao buscar áudios',
|
||||
status: error.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deleta um áudio do banco de dados
|
||||
*
|
||||
* @param audioId - ID do áudio a ser deletado
|
||||
* @param userEmail - Email do usuário (opcional)
|
||||
* @returns Promise com sucesso ou erro
|
||||
*/
|
||||
async deleteAudio(audioId: string, userEmail?: string): Promise<{ success: boolean; message?: string }> {
|
||||
// Usa valores do GlobalFunctions se não forem fornecidos
|
||||
const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
|
||||
|
||||
if (!email) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Email do usuário não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
if (!audioId) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'ID do áudio não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Deletando áudio:', {
|
||||
audioId,
|
||||
userEmail: email,
|
||||
});
|
||||
|
||||
try {
|
||||
// Faz a requisição DELETE com parâmetros na URL
|
||||
const response = await apiService.delete<{ success: boolean; message?: string } | Array<{ success: boolean; message?: string }>>(
|
||||
`${this.DELETE_AUDIO_ENDPOINT}/${email}/${audioId}`
|
||||
);
|
||||
|
||||
console.log('Resposta completa do DELETE:', response);
|
||||
console.log('response.data:', response.data);
|
||||
|
||||
// A API retorna um array com um objeto: [{"success":true}]
|
||||
let result: { success: boolean; message?: string };
|
||||
|
||||
if (Array.isArray(response.data)) {
|
||||
// Se for array, pega o primeiro elemento
|
||||
result = response.data[0];
|
||||
console.log('API retornou array, usando primeiro elemento:', result);
|
||||
} else {
|
||||
// Se for objeto direto
|
||||
result = response.data;
|
||||
console.log('API retornou objeto direto:', result);
|
||||
}
|
||||
|
||||
// Garante que tem a estrutura mínima
|
||||
return {
|
||||
success: result.success ?? true,
|
||||
message: result.message || 'Áudio deletado com sucesso',
|
||||
};
|
||||
} catch (error: any) {
|
||||
console.error('Erro ao deletar áudio:', error);
|
||||
|
||||
throw {
|
||||
success: false,
|
||||
message: error.message || 'Erro ao deletar áudio',
|
||||
status: error.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exporta instância única (Singleton)
|
||||
|
||||
+432
-4
@@ -59,6 +59,54 @@ export interface StoredFolder {
|
||||
chatIds: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface para Folder no banco de dados
|
||||
*/
|
||||
export interface FolderRecord {
|
||||
id: string;
|
||||
name: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface para Chat no banco de dados
|
||||
*/
|
||||
export interface ChatRecord {
|
||||
id: string;
|
||||
title: string;
|
||||
model_id: number;
|
||||
folder_id: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
estabelecimento_id: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface para resposta do GET de chats e folders
|
||||
*/
|
||||
export interface GetChatsAndFoldersResponse {
|
||||
chats: ChatRecord[];
|
||||
folders: FolderRecord[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface para Message no banco de dados
|
||||
*/
|
||||
export interface MessageRecord {
|
||||
id: string;
|
||||
chat_id: string;
|
||||
role: 'user' | 'assistant';
|
||||
content: string;
|
||||
model_id: number;
|
||||
has_attachments: number;
|
||||
input_tokens: number;
|
||||
output_tokens: number;
|
||||
total_tokens: number;
|
||||
cost_usd: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serviço de chat com IA
|
||||
*/
|
||||
@@ -67,6 +115,14 @@ class ChatService {
|
||||
private readonly STORAGE_KEY_CHATS = 'hgtx_chats';
|
||||
private readonly STORAGE_KEY_FOLDERS = 'hgtx_folders';
|
||||
|
||||
// Endpoints para folders e chats
|
||||
private readonly POST_FOLDER_ENDPOINT = '/webhook/codex/post_folders';
|
||||
private readonly GET_CHATS_FOLDERS_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/get_chat_folders';
|
||||
private readonly PUT_CHAT_IN_FOLDER_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/insert_chat_in_folder';
|
||||
private readonly DELETE_FOLDER_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/delete_chat_folder';
|
||||
private readonly DELETE_CHAT_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/delete_chat_messages';
|
||||
private readonly GET_CHAT_MESSAGES_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/get_chat_messages';
|
||||
|
||||
// Formatos de arquivo permitidos (atualmente)
|
||||
private readonly ALLOWED_FILE_TYPES = {
|
||||
// Formatos ativos
|
||||
@@ -280,11 +336,11 @@ class ChatService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deleta um chat
|
||||
* Deleta um chat do localStorage
|
||||
*
|
||||
* @param chatId - ID do chat a ser deletado
|
||||
*/
|
||||
deleteChat(chatId: string): void {
|
||||
deleteChatLocal(chatId: string): void {
|
||||
try {
|
||||
const chats = this.getAllChats();
|
||||
const filteredChats = chats.filter(c => c.id !== chatId);
|
||||
@@ -342,11 +398,11 @@ class ChatService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deleta uma pasta
|
||||
* Deleta uma pasta do localStorage
|
||||
*
|
||||
* @param folderId - ID da pasta a ser deletada
|
||||
*/
|
||||
deleteFolder(folderId: string): void {
|
||||
deleteFolderLocal(folderId: string): void {
|
||||
try {
|
||||
const folders = this.getAllFolders();
|
||||
const filteredFolders = folders.filter(f => f.id !== folderId);
|
||||
@@ -476,6 +532,378 @@ class ChatService {
|
||||
getMaxAttachments(): number {
|
||||
return this.MAX_ATTACHMENTS;
|
||||
}
|
||||
|
||||
// ===== MÉTODOS DE INTEGRAÇÃO COM BANCO DE DADOS =====
|
||||
|
||||
/**
|
||||
* Cria uma nova pasta no banco de dados
|
||||
*
|
||||
* @param name - Nome da pasta
|
||||
* @param userEmail - Email do usuário (opcional)
|
||||
* @returns Promise com sucesso ou erro
|
||||
*/
|
||||
async createFolder(name: string, userEmail?: string): Promise<{ success: boolean; folder?: FolderRecord }> {
|
||||
const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
|
||||
|
||||
if (!email) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Email do usuário não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
if (!name || name.trim().length === 0) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Nome da pasta não pode estar vazio',
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Criando pasta:', {
|
||||
name,
|
||||
userEmail: email,
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await apiService.post<Array<{ success: boolean; user_email?: string; name?: string }>>(
|
||||
this.POST_FOLDER_ENDPOINT,
|
||||
{
|
||||
user_email: email,
|
||||
name: name.trim(),
|
||||
}
|
||||
);
|
||||
|
||||
console.log('Resposta completa do POST:', response);
|
||||
console.log('response.data:', response.data);
|
||||
|
||||
// A API retorna um array com um objeto: [{"success":true, ...}]
|
||||
let result: { success: boolean; user_email?: string; name?: string };
|
||||
|
||||
if (Array.isArray(response.data)) {
|
||||
result = response.data[0];
|
||||
console.log('API retornou array, usando primeiro elemento:', result);
|
||||
} else {
|
||||
result = response.data as any;
|
||||
console.log('API retornou objeto direto:', result);
|
||||
}
|
||||
|
||||
return {
|
||||
success: result.success ?? true,
|
||||
};
|
||||
} catch (error: any) {
|
||||
console.error('Erro ao criar pasta:', error);
|
||||
|
||||
throw {
|
||||
success: false,
|
||||
message: error.message || 'Erro ao criar pasta',
|
||||
status: error.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Busca todos os chats e pastas do usuário
|
||||
*
|
||||
* @param userEmail - Email do usuário (opcional)
|
||||
* @returns Promise com chats e folders
|
||||
*/
|
||||
async getChatsAndFolders(userEmail?: string): Promise<GetChatsAndFoldersResponse> {
|
||||
const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
|
||||
|
||||
if (!email) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Email do usuário não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Buscando chats e pastas:', {
|
||||
userEmail: email,
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await apiService.get<Array<{ result: GetChatsAndFoldersResponse }>>(
|
||||
`${this.GET_CHATS_FOLDERS_ENDPOINT}/${email}`
|
||||
);
|
||||
|
||||
console.log('Resposta completa da API:', response);
|
||||
console.log('response.data:', response.data);
|
||||
|
||||
// A API retorna um array com um objeto "result": [{"result": {"chats": [...], "folders": [...]}}]
|
||||
let result: GetChatsAndFoldersResponse;
|
||||
|
||||
if (Array.isArray(response.data) && response.data.length > 0) {
|
||||
result = response.data[0].result;
|
||||
console.log('API retornou array com result:', result);
|
||||
} else if ((response.data as any).result) {
|
||||
result = (response.data as any).result;
|
||||
console.log('API retornou objeto com result:', result);
|
||||
} else {
|
||||
// Fallback: retorna vazio
|
||||
console.warn('Estrutura inesperada da resposta');
|
||||
result = { chats: [], folders: [] };
|
||||
}
|
||||
|
||||
// Garante que chats e folders são arrays
|
||||
return {
|
||||
chats: Array.isArray(result.chats) ? result.chats : [],
|
||||
folders: Array.isArray(result.folders) ? result.folders : [],
|
||||
};
|
||||
} catch (error: any) {
|
||||
console.error('Erro ao buscar chats e pastas:', error);
|
||||
|
||||
throw {
|
||||
success: false,
|
||||
message: error.message || 'Erro ao buscar chats e pastas',
|
||||
status: error.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move um chat para dentro de uma pasta
|
||||
*
|
||||
* @param chatId - ID do chat
|
||||
* @param folderId - ID da pasta
|
||||
* @returns Promise com sucesso ou erro
|
||||
*/
|
||||
async moveChatToFolder(chatId: string, folderId: string): Promise<{ success: boolean }> {
|
||||
if (!chatId || !folderId) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Chat ID e Folder ID são obrigatórios',
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Movendo chat para pasta:', {
|
||||
chatId,
|
||||
folderId,
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await apiService.put<Array<{ success: boolean }>>(
|
||||
`${this.PUT_CHAT_IN_FOLDER_ENDPOINT}/${folderId}/${chatId}`
|
||||
);
|
||||
|
||||
console.log('Resposta completa do PUT:', response);
|
||||
console.log('response.data:', response.data);
|
||||
|
||||
// A API retorna um array com um objeto: [{"success":true}]
|
||||
let result: { success: boolean };
|
||||
|
||||
if (Array.isArray(response.data)) {
|
||||
result = response.data[0];
|
||||
console.log('API retornou array, usando primeiro elemento:', result);
|
||||
} else {
|
||||
result = response.data;
|
||||
console.log('API retornou objeto direto:', result);
|
||||
}
|
||||
|
||||
return {
|
||||
success: result.success ?? true,
|
||||
};
|
||||
} catch (error: any) {
|
||||
console.error('Erro ao mover chat para pasta:', error);
|
||||
|
||||
throw {
|
||||
success: false,
|
||||
message: error.message || 'Erro ao mover chat para pasta',
|
||||
status: error.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deleta uma pasta do banco de dados
|
||||
*
|
||||
* @param folderId - ID da pasta
|
||||
* @param userEmail - Email do usuário (opcional)
|
||||
* @returns Promise com sucesso ou erro
|
||||
*/
|
||||
async deleteFolder(folderId: string, userEmail?: string): Promise<{ success: boolean }> {
|
||||
const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
|
||||
|
||||
if (!email) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Email do usuário não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
if (!folderId) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'ID da pasta não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Deletando pasta:', {
|
||||
folderId,
|
||||
userEmail: email,
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await apiService.delete<Array<{ success: boolean }>>(
|
||||
`${this.DELETE_FOLDER_ENDPOINT}/${email}/${folderId}`
|
||||
);
|
||||
|
||||
console.log('Resposta completa do DELETE:', response);
|
||||
console.log('response.data:', response.data);
|
||||
|
||||
// A API retorna um array com um objeto: [{"success":true}]
|
||||
let result: { success: boolean };
|
||||
|
||||
if (Array.isArray(response.data)) {
|
||||
result = response.data[0];
|
||||
console.log('API retornou array, usando primeiro elemento:', result);
|
||||
} else {
|
||||
result = response.data;
|
||||
console.log('API retornou objeto direto:', result);
|
||||
}
|
||||
|
||||
return {
|
||||
success: result.success ?? true,
|
||||
};
|
||||
} catch (error: any) {
|
||||
console.error('Erro ao deletar pasta:', error);
|
||||
|
||||
throw {
|
||||
success: false,
|
||||
message: error.message || 'Erro ao deletar pasta',
|
||||
status: error.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deleta um chat do banco de dados
|
||||
*
|
||||
* @param chatId - ID do chat
|
||||
* @param userEmail - Email do usuário (opcional)
|
||||
* @returns Promise com sucesso ou erro
|
||||
*/
|
||||
async deleteChat(chatId: string, userEmail?: string): Promise<{ success: boolean }> {
|
||||
const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
|
||||
|
||||
if (!email) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Email do usuário não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
if (!chatId) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'ID do chat não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Deletando chat:', {
|
||||
chatId,
|
||||
userEmail: email,
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await apiService.delete<Array<{ success: boolean }>>(
|
||||
`${this.DELETE_CHAT_ENDPOINT}/${email}/${chatId}`
|
||||
);
|
||||
|
||||
console.log('Resposta completa do DELETE:', response);
|
||||
console.log('response.data:', response.data);
|
||||
|
||||
// A API retorna um array com um objeto: [{"success":true}]
|
||||
let result: { success: boolean };
|
||||
|
||||
if (Array.isArray(response.data)) {
|
||||
result = response.data[0];
|
||||
console.log('API retornou array, usando primeiro elemento:', result);
|
||||
} else {
|
||||
result = response.data;
|
||||
console.log('API retornou objeto direto:', result);
|
||||
}
|
||||
|
||||
return {
|
||||
success: result.success ?? true,
|
||||
};
|
||||
} catch (error: any) {
|
||||
console.error('Erro ao deletar chat:', error);
|
||||
|
||||
throw {
|
||||
success: false,
|
||||
message: error.message || 'Erro ao deletar chat',
|
||||
status: error.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Busca todas as mensagens de um chat específico
|
||||
*
|
||||
* @param chatId - ID do chat
|
||||
* @param userEmail - Email do usuário (opcional)
|
||||
* @returns Promise com array de mensagens
|
||||
*/
|
||||
async getChatMessages(chatId: string, userEmail?: string): Promise<MessageRecord[]> {
|
||||
const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
|
||||
|
||||
if (!email) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Email do usuário não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
if (!chatId) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'ID do chat não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Buscando mensagens do chat:', {
|
||||
chatId,
|
||||
userEmail: email,
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await apiService.get<MessageRecord[]>(
|
||||
`${this.GET_CHAT_MESSAGES_ENDPOINT}/${email}/${chatId}`
|
||||
);
|
||||
|
||||
console.log('Resposta completa da API:', response);
|
||||
console.log('response.data:', response.data);
|
||||
console.log('É array?:', Array.isArray(response.data));
|
||||
|
||||
// A API retorna diretamente o array de mensagens
|
||||
// Garante que sempre retorna um array
|
||||
if (Array.isArray(response.data)) {
|
||||
return response.data;
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
// Se a resposta for um objeto com uma propriedade 'messages' ou similar
|
||||
console.warn('API retornou objeto em vez de array:', response.data);
|
||||
|
||||
// Tenta encontrar o array dentro do objeto
|
||||
if (Array.isArray((response.data as any).messages)) {
|
||||
return (response.data as any).messages;
|
||||
} else if (Array.isArray((response.data as any).data)) {
|
||||
return (response.data as any).data;
|
||||
}
|
||||
}
|
||||
|
||||
// Se não conseguir extrair array, retorna vazio
|
||||
console.warn('Não foi possível extrair array de mensagens da resposta');
|
||||
return [];
|
||||
} catch (error: any) {
|
||||
console.error('Erro ao buscar mensagens:', error);
|
||||
|
||||
throw {
|
||||
success: false,
|
||||
message: error.message || 'Erro ao buscar mensagens',
|
||||
status: error.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exporta instância única (Singleton)
|
||||
|
||||
@@ -16,6 +16,35 @@ export interface ImageGenerationResponse {
|
||||
message: string; // Descrição original
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface para uma imagem armazenada no banco de dados
|
||||
*/
|
||||
export interface ImageRecord {
|
||||
id: string;
|
||||
user_email: string;
|
||||
estabelecimento_id: number;
|
||||
description: string;
|
||||
model: string;
|
||||
image_url: string;
|
||||
size: ImageSize;
|
||||
cost_usd: string;
|
||||
total_tokens: number;
|
||||
input_tokens: number;
|
||||
output_tokens: number;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface para resposta paginada de imagens
|
||||
*/
|
||||
export interface GetImagesResponse {
|
||||
images: ImageRecord[];
|
||||
total: number;
|
||||
page: number;
|
||||
per_page: number;
|
||||
total_pages: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface para os dados necessários para geração de imagem
|
||||
*/
|
||||
@@ -55,6 +84,8 @@ export const IMAGE_SIZE_OPTIONS = {
|
||||
*/
|
||||
class ImageGenerationService {
|
||||
private readonly IMAGE_GENERATION_ENDPOINT = '/webhook/codex/image_generator';
|
||||
private readonly GET_IMAGES_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/get_images';
|
||||
private readonly DELETE_IMAGE_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/delete_images';
|
||||
|
||||
/**
|
||||
* Gera uma imagem a partir de uma descrição em texto
|
||||
@@ -213,6 +244,150 @@ class ImageGenerationService {
|
||||
throw new Error('Não foi possível baixar a imagem');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lista imagens do banco de dados com paginação
|
||||
*
|
||||
* @param userEmail - Email do usuário
|
||||
* @param page - Número da página (padrão: 1)
|
||||
* @param perPage - Quantidade de itens por página (padrão: 10)
|
||||
* @returns Promise com a resposta paginada
|
||||
*/
|
||||
async getImages(
|
||||
userEmail?: string,
|
||||
page: number = 1,
|
||||
perPage: number = 10
|
||||
): Promise<ImageRecord[]> {
|
||||
// Usa valores do GlobalFunctions se não forem fornecidos
|
||||
const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
|
||||
|
||||
if (!email) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Email do usuário não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Buscando imagens:', {
|
||||
userEmail: email,
|
||||
page,
|
||||
perPage,
|
||||
});
|
||||
|
||||
try {
|
||||
// Faz a requisição GET com parâmetros na URL e query
|
||||
const response = await apiService.get<ImageRecord[]>(
|
||||
`${this.GET_IMAGES_ENDPOINT}/${email}`,
|
||||
{
|
||||
params: {
|
||||
page: page.toString(),
|
||||
per_page: perPage.toString(),
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
console.log('Resposta completa da API:', response);
|
||||
console.log('response.data:', response.data);
|
||||
console.log('É array?:', Array.isArray(response.data));
|
||||
|
||||
// A API retorna diretamente o array de imagens
|
||||
// Garante que sempre retorna um array
|
||||
if (Array.isArray(response.data)) {
|
||||
return response.data;
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
// Se a resposta for um objeto com uma propriedade 'images' ou similar
|
||||
console.warn('API retornou objeto em vez de array:', response.data);
|
||||
|
||||
// Tenta encontrar o array dentro do objeto
|
||||
if (Array.isArray((response.data as any).images)) {
|
||||
return (response.data as any).images;
|
||||
} else if (Array.isArray((response.data as any).data)) {
|
||||
return (response.data as any).data;
|
||||
}
|
||||
}
|
||||
|
||||
// Se não conseguir extrair array, retorna vazio
|
||||
console.warn('Não foi possível extrair array de imagens da resposta');
|
||||
return [];
|
||||
} catch (error: any) {
|
||||
console.error('Erro ao buscar imagens:', error);
|
||||
|
||||
throw {
|
||||
success: false,
|
||||
message: error.message || 'Erro ao buscar imagens',
|
||||
status: error.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deleta uma imagem do banco de dados
|
||||
*
|
||||
* @param imageId - ID da imagem a ser deletada
|
||||
* @param userEmail - Email do usuário (opcional)
|
||||
* @returns Promise com sucesso ou erro
|
||||
*/
|
||||
async deleteImage(imageId: string, userEmail?: string): Promise<{ success: boolean; message?: string }> {
|
||||
// Usa valores do GlobalFunctions se não forem fornecidos
|
||||
const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
|
||||
|
||||
if (!email) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Email do usuário não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
if (!imageId) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'ID da imagem não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Deletando imagem:', {
|
||||
imageId,
|
||||
userEmail: email,
|
||||
});
|
||||
|
||||
try {
|
||||
// Faz a requisição DELETE com parâmetros na URL
|
||||
const response = await apiService.delete<{ success: boolean; message?: string } | Array<{ success: boolean; message?: string }>>(
|
||||
`${this.DELETE_IMAGE_ENDPOINT}/${email}/${imageId}`
|
||||
);
|
||||
|
||||
console.log('Resposta completa do DELETE:', response);
|
||||
console.log('response.data:', response.data);
|
||||
|
||||
// A API pode retornar um array com um objeto: [{"success":true}]
|
||||
// ou diretamente um objeto: {"success":true}
|
||||
let result: { success: boolean; message?: string };
|
||||
|
||||
if (Array.isArray(response.data)) {
|
||||
// Se for array, pega o primeiro elemento
|
||||
result = response.data[0];
|
||||
console.log('API retornou array, usando primeiro elemento:', result);
|
||||
} else {
|
||||
// Se for objeto direto
|
||||
result = response.data;
|
||||
console.log('API retornou objeto direto:', result);
|
||||
}
|
||||
|
||||
// Garante que tem a estrutura mínima
|
||||
return {
|
||||
success: result.success ?? true,
|
||||
message: result.message || 'Imagem deletada com sucesso',
|
||||
};
|
||||
} catch (error: any) {
|
||||
console.error('Erro ao deletar imagem:', error);
|
||||
|
||||
throw {
|
||||
success: false,
|
||||
message: error.message || 'Erro ao deletar imagem',
|
||||
status: error.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exporta instância única (Singleton)
|
||||
|
||||
@@ -11,6 +11,22 @@ export interface TranscriptionResponse {
|
||||
message: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface para uma transcrição armazenada no banco de dados
|
||||
*/
|
||||
export interface TranscriptionRecord {
|
||||
id: string;
|
||||
user_email: string;
|
||||
estabelecimento_id: number;
|
||||
audio_file_name: string;
|
||||
audio_duration_seconds: number;
|
||||
transcription_text: string;
|
||||
model: string;
|
||||
audio_url: string;
|
||||
cost_usd: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface para os dados necessários para transcrição
|
||||
*/
|
||||
@@ -25,6 +41,8 @@ export interface TranscriptionRequest {
|
||||
*/
|
||||
class TranscriptionService {
|
||||
private readonly TRANSCRIPTION_ENDPOINT = '/webhook/codex/transcrever_audio';
|
||||
private readonly GET_TRANSCRIPTIONS_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/get_transcrever_audio';
|
||||
private readonly DELETE_TRANSCRIPTION_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/delete_transcrever_audio';
|
||||
|
||||
/**
|
||||
* Transcreve um arquivo de áudio
|
||||
@@ -105,6 +123,149 @@ class TranscriptionService {
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Lista transcrições do banco de dados com paginação
|
||||
*
|
||||
* @param userEmail - Email do usuário
|
||||
* @param page - Número da página (padrão: 1)
|
||||
* @param perPage - Quantidade de itens por página (padrão: 10)
|
||||
* @returns Promise com o array de transcrições
|
||||
*/
|
||||
async getTranscriptions(
|
||||
userEmail?: string,
|
||||
page: number = 1,
|
||||
perPage: number = 10
|
||||
): Promise<TranscriptionRecord[]> {
|
||||
// Usa valores do GlobalFunctions se não forem fornecidos
|
||||
const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
|
||||
|
||||
if (!email) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Email do usuário não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Buscando transcrições:', {
|
||||
userEmail: email,
|
||||
page,
|
||||
perPage,
|
||||
});
|
||||
|
||||
try {
|
||||
// Faz a requisição GET com parâmetros na URL e query
|
||||
const response = await apiService.get<TranscriptionRecord[]>(
|
||||
`${this.GET_TRANSCRIPTIONS_ENDPOINT}/${email}`,
|
||||
{
|
||||
params: {
|
||||
page: page.toString(),
|
||||
per_page: perPage.toString(),
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
console.log('Resposta completa da API:', response);
|
||||
console.log('response.data:', response.data);
|
||||
console.log('É array?:', Array.isArray(response.data));
|
||||
|
||||
// A API retorna diretamente o array de transcrições
|
||||
// Garante que sempre retorna um array
|
||||
if (Array.isArray(response.data)) {
|
||||
return response.data;
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
// Se a resposta for um objeto com uma propriedade 'transcriptions' ou similar
|
||||
console.warn('API retornou objeto em vez de array:', response.data);
|
||||
|
||||
// Tenta encontrar o array dentro do objeto
|
||||
if (Array.isArray((response.data as any).transcriptions)) {
|
||||
return (response.data as any).transcriptions;
|
||||
} else if (Array.isArray((response.data as any).data)) {
|
||||
return (response.data as any).data;
|
||||
}
|
||||
}
|
||||
|
||||
// Se não conseguir extrair array, retorna vazio
|
||||
console.warn('Não foi possível extrair array de transcrições da resposta');
|
||||
return [];
|
||||
} catch (error: any) {
|
||||
console.error('Erro ao buscar transcrições:', error);
|
||||
|
||||
throw {
|
||||
success: false,
|
||||
message: error.message || 'Erro ao buscar transcrições',
|
||||
status: error.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deleta uma transcrição do banco de dados
|
||||
*
|
||||
* @param transcriptionId - ID da transcrição a ser deletada
|
||||
* @param userEmail - Email do usuário (opcional)
|
||||
* @returns Promise com sucesso ou erro
|
||||
*/
|
||||
async deleteTranscription(transcriptionId: string, userEmail?: string): Promise<{ success: boolean; message?: string }> {
|
||||
// Usa valores do GlobalFunctions se não forem fornecidos
|
||||
const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
|
||||
|
||||
if (!email) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'Email do usuário não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
if (!transcriptionId) {
|
||||
throw {
|
||||
success: false,
|
||||
message: 'ID da transcrição não fornecido',
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Deletando transcrição:', {
|
||||
transcriptionId,
|
||||
userEmail: email,
|
||||
});
|
||||
|
||||
try {
|
||||
// Faz a requisição DELETE com parâmetros na URL
|
||||
const response = await apiService.delete<{ success: boolean; message?: string } | Array<{ success: boolean; message?: string }>>(
|
||||
`${this.DELETE_TRANSCRIPTION_ENDPOINT}/${email}/${transcriptionId}`
|
||||
);
|
||||
|
||||
console.log('Resposta completa do DELETE:', response);
|
||||
console.log('response.data:', response.data);
|
||||
|
||||
// A API retorna um array com um objeto: [{"success":true}]
|
||||
let result: { success: boolean; message?: string };
|
||||
|
||||
if (Array.isArray(response.data)) {
|
||||
// Se for array, pega o primeiro elemento
|
||||
result = response.data[0];
|
||||
console.log('API retornou array, usando primeiro elemento:', result);
|
||||
} else {
|
||||
// Se for objeto direto
|
||||
result = response.data;
|
||||
console.log('API retornou objeto direto:', result);
|
||||
}
|
||||
|
||||
// Garante que tem a estrutura mínima
|
||||
return {
|
||||
success: result.success ?? true,
|
||||
message: result.message || 'Transcrição deletada com sucesso',
|
||||
};
|
||||
} catch (error: any) {
|
||||
console.error('Erro ao deletar transcrição:', error);
|
||||
|
||||
throw {
|
||||
success: false,
|
||||
message: error.message || 'Erro ao deletar transcrição',
|
||||
status: error.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exporta instância única (Singleton)
|
||||
|
||||
Reference in New Issue
Block a user