recebe as informações agora via pusher ao invés de requests da api, pra evitar sobrecarga no servidor
This commit is contained in:
parent
16a178b585
commit
47c3b9877a
13
index.html
13
index.html
|
|
@ -2,7 +2,12 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src https://autoatend.linco.work">
|
||||
<meta http-equiv="Content-Security-Policy" content="
|
||||
default-src 'self';
|
||||
script-src 'self' 'unsafe-inline';
|
||||
style-src 'self' 'unsafe-inline';
|
||||
connect-src 'self' ws://autoatend.linco.work:6001 ws://localhost:6001;
|
||||
">
|
||||
<title>Tela de Atendimento</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="res/js/jquery/jquery.js"></script>
|
||||
|
|
@ -14,7 +19,10 @@
|
|||
<ul id="item-list">
|
||||
<!-- Itens serão carregados aqui -->
|
||||
</ul>
|
||||
<button id="next-button" disabled><span id="counter-start"></span> Iniciar atendimento</button>
|
||||
<button id="next-button" disabled>
|
||||
<span id="counter-start"></span>
|
||||
Iniciar atendimento
|
||||
</button>
|
||||
<!-- <button id="sendto-button" disabled>Encaminhar</button> -->
|
||||
<button id="logout-button">Trocar Colaborador</button>
|
||||
|
||||
|
|
@ -35,6 +43,7 @@
|
|||
<button id="save-button">Salvar</button>
|
||||
</div>
|
||||
|
||||
<script src="res/js/pusher.min.js"></script>
|
||||
<script src="renderer.js"></script>
|
||||
|
||||
</body>
|
||||
|
|
|
|||
109
main.js
109
main.js
|
|
@ -13,19 +13,16 @@ let updateWin;
|
|||
|
||||
const dataPath = path.join(__dirname, 'data.json'); // Caminho para o JSON (backup local)
|
||||
const apiUrl = 'https://autoatend.linco.work/api/v1/';
|
||||
// const apiUrl = 'http://_lara10-autoatend.devel/api/v1/';
|
||||
|
||||
const pusherUrl = 'autoatend.linco.work';
|
||||
// const pusherUrl = 'localhost';
|
||||
|
||||
|
||||
autoUpdater.autoDownload = false;
|
||||
autoUpdater.autoInstallOnAppQuit = true;
|
||||
|
||||
|
||||
//// 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() {
|
||||
try {
|
||||
|
|
@ -50,12 +47,13 @@ async function readData() {
|
|||
async function fetchDataFromAPI() {
|
||||
//executa uma vez e a cada 30 segundos
|
||||
|
||||
//TODO propicio para fazer um webhook nessas funções que repetem a chamada de requisições em busca de alterações
|
||||
getAndUpdateDataStorage();
|
||||
//TODO propicio para fazer um websockt nessas funções que repetem a chamada de requisições em busca de alterações
|
||||
|
||||
getDataAndUpdateFloatingBtn();
|
||||
|
||||
const updData = setInterval(()=>{
|
||||
getAndUpdateDataStorage();
|
||||
},10000);
|
||||
getDataAndUpdateFloatingBtn();
|
||||
},3000);
|
||||
|
||||
const updVersion = setTimeout(()=>{
|
||||
if(pjson.isBuildNow){
|
||||
|
|
@ -65,74 +63,12 @@ async function fetchDataFromAPI() {
|
|||
}
|
||||
|
||||
// Função para coletar a lista de atendimentos do servidor, vai ser chamada uma vez e a cada 30s
|
||||
async function getAndUpdateDataStorage (){
|
||||
async function getDataAndUpdateFloatingBtn (){
|
||||
|
||||
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();
|
||||
const proximos = JSON.parse(await floatingWin.webContents.executeJavaScript("localStorage.getItem('proximos')"));
|
||||
let count = proximos.length;
|
||||
//lista a contagem no botão flutuante
|
||||
floatingWin.webContents.send('update-count', count);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -360,7 +296,6 @@ app.whenReady().then(async () => {
|
|||
createFloatingWindow();
|
||||
createMainWindow();
|
||||
}
|
||||
|
||||
}
|
||||
createUpdateWindow();
|
||||
|
||||
|
|
@ -423,6 +358,12 @@ async function getSelectedOperatorId() {
|
|||
});
|
||||
}
|
||||
|
||||
ipcMain.handle('get-pusher-config', async () => {
|
||||
// Obtenha sua chave e host de forma segura aqui (ambiente, .env, etc.)
|
||||
const PUSHER_APP_KEY = process.env.PUSHER_APP_KEY || '1feb970af7708cb';
|
||||
const PUSHER_HOST = process.env.PUSHER_HOST || pusherUrl;
|
||||
return { appKey: PUSHER_APP_KEY, host: PUSHER_HOST };
|
||||
});
|
||||
|
||||
ipcMain.on('update_version', async (event, arg) => {
|
||||
if(updateWin){
|
||||
|
|
@ -682,6 +623,7 @@ ipcMain.on('login-attempt', async (event, credentials) => {
|
|||
// Login bem-sucedido
|
||||
loginWin.webContents.executeJavaScript(`
|
||||
localStorage.setItem("authToken", "${data.api_key}");
|
||||
localStorage.setItem("channel", "${data.channel}");
|
||||
`).then(() => {
|
||||
// Fecha a janela de login e abre a de seleção de operador
|
||||
event.reply('login-response', { success: true });
|
||||
|
|
@ -864,5 +806,12 @@ ipcMain.on('token-exists', async () => {
|
|||
|
||||
|
||||
ipcMain.on('sair', ()=>{
|
||||
app.exit();
|
||||
operatorWin.webContents.executeJavaScript(`
|
||||
localStorage.removeItem("idOperator");
|
||||
localStorage.removeItem("selectedOperator");
|
||||
localStorage.removeItem("salaOperator");
|
||||
localStorage.removeItem("servicosOperator");
|
||||
`).then(() => {
|
||||
app.exit();
|
||||
});
|
||||
});
|
||||
|
|
@ -29,8 +29,10 @@
|
|||
<script>
|
||||
$(function(){
|
||||
let opse = localStorage.getItem('selectedOperator');
|
||||
let vs = localStorage.getItem('version');
|
||||
setTimeout(()=>{
|
||||
$('span.op').text(opse);
|
||||
$('#version').text(vs);
|
||||
},2000);
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ const operatorSelect = document.getElementById('operator-select');
|
|||
const selectButton = document.getElementById('select-button');
|
||||
const errorMessage = document.getElementById('error-message');
|
||||
const quitButton = document.getElementById('sair-button');
|
||||
const verionSpan = document.getElementById('version');
|
||||
|
||||
// Carrega a lista de operadores ao iniciar
|
||||
window.addEventListener('DOMContentLoaded', async () => {
|
||||
|
|
@ -68,6 +69,12 @@ const selectedOperatorValue = operatorSelect.value;
|
|||
}
|
||||
});
|
||||
|
||||
window.electronAPI.showVersion((version) => {
|
||||
verionSpan.textContent = `${version}`;
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Recebe resposta do processo de seleção
|
||||
window.electronAPI.onOperatorResponse((response) => {
|
||||
if (!response.success) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ const { contextBridge, ipcRenderer } = require('electron');
|
|||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
getOperators: () => ipcRenderer.invoke('get-operators'),
|
||||
selectOperator: (operatorName) => ipcRenderer.send('select-operator', operatorName),
|
||||
showVersion: (version) => ipcRenderer.on('show-version', version),
|
||||
onOperatorResponse: (callback) => ipcRenderer.on('operator-response', (_event, response) => callback(response)),
|
||||
quitApp : () => ipcRenderer.send('sair'),
|
||||
});
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "autoatendcolab",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"main": "main.js",
|
||||
"isBuildNow": true,
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
|||
//carrega todos os atendimentos na fila
|
||||
onLoadData: (callback) => ipcRenderer.on('load-data', (_event, data) => callback(data)),
|
||||
|
||||
//carrega todos os atendimentoa via pusher
|
||||
getPusherConfig: () => ipcRenderer.invoke('get-pusher-config'),
|
||||
sendPusherEvent: (callback) => ipcRenderer.on('pusher-event-received', (_event, data) => callback(data)),
|
||||
|
||||
//seleciona o atendimento atual
|
||||
selectAtendID: (callback) => ipcRenderer.on('select-atend-id', (_event, data) => callback(data)),
|
||||
|
||||
|
|
|
|||
53
renderer.js
53
renderer.js
|
|
@ -24,6 +24,55 @@ window.electronAPI.onLoadData((data) => {
|
|||
populateList(data[0]);
|
||||
});
|
||||
|
||||
async function initializePusher() {
|
||||
if (typeof window.electronAPI === 'undefined' || !window.electronAPI.getPusherConfig) {
|
||||
console.error('electronAPI not available or getPusherConfig method missing.');
|
||||
return;
|
||||
}
|
||||
|
||||
const pusherConfig = await window.electronAPI.getPusherConfig();
|
||||
const PUSHER_APP_KEY = pusherConfig.appKey;
|
||||
let host = pusherConfig.host;
|
||||
|
||||
const channelLocal = localStorage.getItem('channel');
|
||||
const colabId = localStorage.getItem('idOperator');
|
||||
|
||||
if (channelLocal && PUSHER_APP_KEY) {
|
||||
Pusher.logToConsole = true;
|
||||
|
||||
var pusher = new Pusher(PUSHER_APP_KEY, {
|
||||
wsHost: host,
|
||||
wsPort: 6001,
|
||||
wssPort: 6001,
|
||||
forceTLS: false,
|
||||
enableStats: false,
|
||||
enabledTransports: ['ws','wss'],
|
||||
cluster: 'mt1'
|
||||
});
|
||||
|
||||
var channel = pusher.subscribe('chat.' + channelLocal + '_' + colabId);
|
||||
channel.bind('message-sent', function(r) {
|
||||
let count = r.data.fila.original.length;
|
||||
console.log(r.data.fila.original);
|
||||
localStorage.setItem('proximos',JSON.stringify(r.data.fila.original));
|
||||
|
||||
populateList(r.data.currentData.original);
|
||||
|
||||
});
|
||||
|
||||
pusher.connection.bind('error', function(err) {
|
||||
console.error('Pusher connection error:', err);
|
||||
});
|
||||
|
||||
console.log('Host de conexão:', host);
|
||||
} else {
|
||||
console.warn('User not authenticated or Pusher APP_KEY not available. Private channel not subscribed.');
|
||||
}
|
||||
}
|
||||
|
||||
initializePusher();
|
||||
|
||||
|
||||
//chama o proximo da fila ao abrir a janela de atendimentos
|
||||
window.electronAPI.selectAtendID((data)=>{
|
||||
if(!data){
|
||||
|
|
@ -50,7 +99,7 @@ function populateList(currentData) {
|
|||
|
||||
// Adiciona os outros itens apenas para visualização (opcional)
|
||||
const proximos = JSON.parse(datastorage);
|
||||
var count = 8;
|
||||
var count = 5;
|
||||
|
||||
itemList.innerHTML = ''; // Limpa a lista anterior
|
||||
if (!proximos || proximos.length === 0 || !currentData) {
|
||||
|
|
@ -58,7 +107,7 @@ function populateList(currentData) {
|
|||
const dec_counter = setInterval(() => {
|
||||
count = count -1;
|
||||
counterStart.innerHTML = `[ ${count} ]`;
|
||||
if (count <= 0 && currentData) {
|
||||
if (count <= 0 || !currentData) {
|
||||
counterStart.innerHTML = '';
|
||||
nextButton.disabled = false;
|
||||
clearInterval(dec_counter);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue