From eb5f91b8c9ecd6745ae74cba0a00d76fd750cb35 Mon Sep 17 00:00:00 2001 From: Eder Moraes <54563944+edermcastro@users.noreply.github.com> Date: Sat, 31 May 2025 23:05:04 -0300 Subject: [PATCH] =?UTF-8?q?adicionado=20funcionalidade=20pra=20atualizar?= =?UTF-8?q?=20a=20lista=20de=20atendimentos=20no=20backend=20trazida=20pel?= =?UTF-8?q?a=20api=20do=20electron,=20corre=C3=A7=C3=B5es=20para=20telas?= =?UTF-8?q?=20no=20main=20e=20renderer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- floating.html | 58 +-------------------------- floating.js | 2 +- index.html | 69 ++------------------------------ main.js | 106 ++++++++++++++++++++++++++++++++++++++++---------- package.json | 2 +- preload.js | 18 +++++---- renderer.js | 84 +++++++++++++-------------------------- style.css | 4 +- 8 files changed, 133 insertions(+), 210 deletions(-) diff --git a/floating.html b/floating.html index 40bc9e0..0cdbab2 100644 --- a/floating.html +++ b/floating.html @@ -13,62 +13,6 @@ 0 - + \ No newline at end of file diff --git a/floating.js b/floating.js index 65f0429..4b8405a 100644 --- a/floating.js +++ b/floating.js @@ -3,7 +3,7 @@ const countSpan = document.getElementById('count'); // Atualiza a contagem e a cor do botão quando recebe do main process window.electronAPI.onUpdateCount((value) => { - countSpan.textContent = value; + countSpan.innerHTML = value ?? 0; // Verifica a contagem para mudar a cor if (value > 0) { floatButton.classList.add('has-items'); // Adiciona a classe para cor avermelhada diff --git a/index.html b/index.html index 55a2677..7cf0533 100644 --- a/index.html +++ b/index.html @@ -6,14 +6,6 @@ Aguardando atendimento -
@@ -23,80 +15,27 @@ - +
- \ No newline at end of file diff --git a/main.js b/main.js index 821fe2d..bfcdbf6 100644 --- a/main.js +++ b/main.js @@ -17,14 +17,14 @@ const apiUrl = 'https://autoatend.linco.work/api/v1/'; autoUpdater.autoDownload = false; autoUpdater.autoInstallOnAppQuit = true; -// autoUpdater.autoDownloadOnStartup = true; -if(!pjson.isBuildNow){ - require('electron-reload')(__dirname,{ - electron: require(`${__dirname}/node_modules/electron`) - }) -} +//// carrega o electron-reload, buga ao salvar o main.js por conta do fetchDataFromAPI +// if(!pjson.isBuildNow){ +// require('electron-reload')(__dirname,{ +// electron: require(`${__dirname}/node_modules/electron`) +// }) +// } // Função modificada para buscar dados da API async function readData() { @@ -39,25 +39,91 @@ async function readData() { } // Tenta buscar dados da API - return await fetchDataFromAPI(token,colabId); //não usada aqui vai ser disparada via jquery dentro do modulo + return await fetchDataFromAPI(); } catch (error) { console.error("Erro ao buscar dados da API:", error); - - // Fallback: tenta ler do arquivo local em caso de falha na API - try { - const rawData = fs.readFileSync(dataPath, 'utf-8'); - return JSON.parse(rawData); - } catch (localError) { - console.error("Erro ao ler data.json local:", localError); - return []; // Retorna array vazio em caso de erro - } } } // Função para buscar dados da API -async function fetchDataFromAPI(token,colabId) { - //refactorado +async function fetchDataFromAPI() { + //executa uma vez e a cada 30 segundos + getAndUpdateDataStorage(); setInterval(()=>{ + getAndUpdateDataStorage(); + },30000); +} + +// Função para coletar a lista de atendimentos do servidor, vai ser chamada uma vez e a cada 30s +async function getAndUpdateDataStorage (){ + + const token = await getAuthToken(); + const colabId = await floatingWin.webContents.executeJavaScript("localStorage.getItem('idOperator')") + + const url = apiUrl + 'get-proximos/'+colabId; // URL de exemplo para enviar a solicitação + + if (!token && !colabId) { + console.warn("Token or colabId not found in localStorage. API requests will not be made."); + return; // Stop the function if token or colabId is missing + } + + const request = net.request({ + method: 'GET', + url: url, + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer ' + token + } + }); + + request.on('response', (response) => { + let rawData = ''; + + response.on('data', (chunk) => { + rawData += chunk; + }); + + response.on('end', () => { + try { + const parsedData = JSON.parse(rawData); + let proximos = parsedData; + + if (response.statusCode === 200) { + if(!mainWin.isVisible){ + //envia os dados para o loadData atualiza a tela somente se não estiver sendo exibida + mainWin.webContents.send('load-data', proximos); + } + //grava os registros no localstorage + floatingWin.webContents.executeJavaScript("localStorage.setItem('proximos','"+JSON.stringify(proximos)+"')"); + let count = proximos.length; + //lista a contagem no botão flutuante + floatingWin.webContents.send('update-count', count); + console.log(`Dados carregados com sucesso!`); + } else { + console.error(`Erro na requisição: Status code ${response.statusCode}`, parsedData); + // Lidar com o erro adequadamente, talvez enviando uma mensagem para a janela principal + mainWin.webContents.send('api-error', { + message: `Erro ao chamar atendimentos: ${parsedData.message || 'Erro desconhecido'}` + }); + } + } catch (error) { + console.error("Erro ao analisar a resposta JSON:", error); + mainWin.webContents.send('api-error', { + message: `Erro ao processar resposta do servidor.` + }); + } + }); + }); + + request.on('error', (error) => { + console.error("Erro na requisição:", error); + mainWin.webContents.send('api-error', { + message: `Erro ao chamar atendimento: ${error.message}` + }); + }); + + request.end(); + } // Função para verificar se o token existe no localStorage @@ -468,8 +534,8 @@ ipcMain.on('iniciar-atendimento', (event, itemId) => { }); request.on('response', (response) => { - console.log(`STATUS: ${response.statusCode}`); - console.log(`HEADERS: ${JSON.stringify(response.headers)}`); + // console.log(`STATUS: ${response.statusCode}`); + // console.log(`HEADERS: ${JSON.stringify(response.headers)}`); response.on('data', (chunk) => { console.log(`BODY: ${chunk}`); }); diff --git a/package.json b/package.json index dbbecf1..cd5547d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "autoatendcolab", "version": "1.0.0", "main": "main.js", - "isBuildNow": false, + "isBuildNow": true, "scripts": { "start": "electron .", "nodemon": "nodemon --exec electron .", diff --git a/preload.js b/preload.js index 2de3f71..2faad01 100644 --- a/preload.js +++ b/preload.js @@ -1,23 +1,27 @@ const { app, contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('electronAPI', { - onLoadData: (callback) => ipcRenderer.on('load-data', (_event, value) => callback(value)), + //carrega todos os atendimentos na fila + onLoadData: (callback) => ipcRenderer.on('load-data', (_event, data) => callback(data)), + + //seleciona o atendimento atual selectAtendID: (callback) => ipcRenderer.on('select-atend-id', (_event, data) => callback(data)), + + //inicia o atendimento atual iniciaAtendimento: (itemId) => ipcRenderer.send('iniciar-atendimento', itemId), - logoutApp: () => ipcRenderer.send('logout'), + //salva a observação do atendimento saveObservation: (data) => ipcRenderer.send('save-observation', data), + + //sai do colaborador atual + logoutApp: () => ipcRenderer.send('logout'), + //sistema de atualizações updVersion: (callback) => ipcRenderer.on('update_version',(_event,arg) => callback(arg)), updMessage: (callback) => ipcRenderer.on('update_message', (_event,data) => callback(data)), updPercent: (callback) => ipcRenderer.on('update_percent', (_event,data) => callback(data)), atualVersion: (callback) => ipcRenderer.on('atual_version', (_event,data) => callback(data)), updNVersion: (callback) => ipcRenderer.on('update_new_version', (_event,data) => callback(data)), - // updateMessage: (data) => ipcRenderer.send('update_message', data), - // updPercent: (data) => ipcRenderer.send('update_percent', data), - // atualVersion: (data) => ipcRenderer.send('atual_version', data), - // updNVersion: (data) => ipcRenderer.send('update_new_version', data), - }); \ No newline at end of file diff --git a/renderer.js b/renderer.js index 3a920d1..e470e0b 100644 --- a/renderer.js +++ b/renderer.js @@ -8,34 +8,47 @@ const observationText = document.getElementById('observation-text'); const saveButton = document.getElementById('save-button'); const selectedItemNameSpan = document.getElementById('selected-item-name'); const queueNumber = document.getElementById('queue-number'); +const idAtend = document.getElementById('idAtend'); let currentData = []; let selectedItemId = null; let selectedItemName = ''; -// window.electronAPI.onLoadData(() => { -// populateList(); -// // Reseta a view para a lista sempre que os dados são carregados -// showListView(); -// }); +window.electronAPI.onLoadData((data) => { + if(!data){ + return; + } + // Reseta a view para a lista sempre que os dados são carregados + populateList(data[0]); + showListView(); +}); //chama o proximo da fila ao abrir a janela de atendimentos window.electronAPI.selectAtendID((data)=>{ - selectedItemId = data.id; - queueNumber.innerHTML = data ? 'Chamando: '+ /*data.senhaGen + ' - '+*/ data.clientName.toUpperCase() + ' - ' + data.descricaoServico.toUpperCase() : 'Ninguem aguardando atendimento'; + if(!data){ + queueNumber.innerHTML = 'Ninguem aguardando atendimento'; + window.close(); + return; + } + // Reseta a view para a lista sempre que os dados são carregados ao clicar no botão para abrir a janela + populateList(data); + showListView(); + selectedItemId = data.id ?? null; + queueNumber.innerHTML = data ? 'NA VEZ: '+ /*data.senhaGen + ' - '+*/ data.clientName.toUpperCase() + ' - ' + data.descricaoServico.toUpperCase() : 'Ninguem aguardando atendimento'; + }); // Função para popular a lista de itens -function populateList() { +function populateList(currentData) { let datastorage = localStorage.getItem('proximos'); // Adiciona os outros itens apenas para visualização (opcional) const proximos = JSON.parse(datastorage); - + itemList.innerHTML = ''; // Limpa a lista anterior - if (!proximos || proximos.length === 0) { + if (!proximos || proximos.length === 0 || !currentData) { itemList.innerHTML = '
  • Nenhum item encontrado.
  • '; - nextButton.disabled = true; + nextButton.disabled = !currentData; return; } @@ -53,7 +66,7 @@ function populateList() { nextButton.disabled = false; } else { itemList.innerHTML = '
  • Nenhum item para processar.
  • '; - nextButton.disabled = true; + nextButton.disabled = !currentData; selectedItemId = null; selectedItemName = ''; } @@ -61,7 +74,8 @@ function populateList() { // Adiciona os outros itens apenas para visualização (opcional) proximos.slice(1).forEach(item => { const li = document.createElement('li'); - li.textContent = `${item.senhaGen}: ${item.clientName.toUpperCase()} - ${item.attendanceType.toUpperCase()} - ${item.descricaoServico.toUpperCase()}`; + //${item.senhaGen}: + li.textContent = `${item.clientName.toUpperCase()} - ${item.attendanceType.toUpperCase()} - ${item.descricaoServico.toUpperCase()}`; itemList.appendChild(li); }); } @@ -69,13 +83,10 @@ function populateList() { //mostra a tela de listagem e permite iniciar o atendimento function showListView() { - // populateList(); - listView.style.display = 'block'; encaminharView.style.display = 'none'; observationView.style.display = 'none'; observationText.value = ''; // Limpa a textarea - // nextButton.disabled = !selectedItemId; // Habilita/desabilita baseado na seleção } @@ -121,44 +132,3 @@ logoutButton.addEventListener('click',()=>{ // }); // Inicialmente, mostra a view da lista (estará vazia até receber dados) - - - -//não vai ser usado timer pois é usado no floatbuttom, ele atualiza com timer -//essa função vai ser chamada apenas quando algum registro já estiver sido atendido -function updRemoteList() { - if (!token && !colabId) { - console.warn("Token or colabId not found in localStorage. API requests will not be made."); - return; // Stop the function if token or colabId is missing - } - - $.ajax(apiUrl + 'get-proximos/'+colabId, { - method: 'GET', - headers: { 'Authorization': 'Bearer '+token }, - processData: false, - contentType: false, - dataType: 'JSON', - success: function(response) { - console.log('Resposta:', response); - // Ensure the response is valid JSON before parsing - try { - localStorage.setItem('proximos', JSON.stringify(response)); - } catch (e) { - console.error("Error parsing JSON response:", e); - console.error("Response text:", response); // Log the raw response for debugging - } - }, - error: function(xhr, status, error) { - console.error('Erro na requisição:', status, error); - console.error('Response Text:', xhr.responseText); // Log the response text for debugging - // Optionally, handle different error codes: - if (xhr.status === 401) { - console.warn("Unauthorized. Token might be invalid."); - // You could redirect the user to a login page here. - } else if (xhr.status === 404) { - console.warn("Resource not found. Check the API endpoint."); - } - } - }); - -} \ No newline at end of file diff --git a/style.css b/style.css index 5fd36ca..f7b4185 100644 --- a/style.css +++ b/style.css @@ -2,7 +2,7 @@ body { font-family: sans-serif; margin: 0; - padding: 0; + padding: 10px; background-color: transparent; /* Para janela flutuante */ overflow: hidden; /* Evita barras de rolagem indesejadas na flutuante */ -webkit-app-region: drag; @@ -104,7 +104,7 @@ button:disabled { } textarea { - width: 95%; /* Ajuste conforme necessário */ + width: calc(100% - 10px); margin-top: 10px; margin-bottom: 10px; border: 1px solid #ccc;