import { app, BrowserWindow, screen } from 'electron' import path from 'path' import { fileURLToPath } from 'url' import started from 'electron-squirrel-startup' import express from 'express' import { Agent } from 'undici' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const serverApp = express() const port = 3000 const agent = new Agent({ connectTimeout: 0, headersTimeout: 0, bodyTimeout: 0, }) serverApp.use(express.static(path.join(__dirname, 'public'))) serverApp.use(express.json()) serverApp.get('/', (req, res) => { res.sendFile(path.join(__dirname, 'index.html')) }) const validateCPF = (cpf) => { if (!cpf) return false cpf = cpf.replace(/\D/g, '') if (cpf.length !== 11 || /^(\d)\1+$/.test(cpf)) return false const calc = (slice) => ((slice.split('').reduce((sum, num, i) => sum + num * (slice.length + 1 - i), 0) * 10) % 11) % 10 return calc(cpf.slice(0, 9)) == cpf[9] && calc(cpf.slice(0, 10)) == cpf[10] ? cpf : false } let adminCredentials, baseUrl, cookies, userData, cnesUnidades, procedimentosFaturaveis, solicitacoesEmFila serverApp.post('/login', async (req, res) => { adminCredentials = req.body baseUrl = `https://www.${adminCredentials.municipio.toString().toLowerCase()}-${adminCredentials.estado.toString().toLowerCase()}` const loginVivver = async (login, senha) => { const cookiesArr = [] const cookiesFinal = {} try { const response = await fetch(`${baseUrl}.vivver.com/login/create`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', Origin: `${baseUrl}.vivver.com`, Referer: `${baseUrl}.vivver.com/login?conta=${login}`, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36', }, body: `utf8=%E2%9C%93&page=&page_query=&conta=${login}&password=${encodeURIComponent(senha)}&commit=Entrar`, }) if (!response.ok) { console.log(`Falhou ao logar e pegar os Cookies. Status: ${response.status}`) res.json({ errorCode: 1, errorMessage: `Falhou ao logar e pegar os Cookies. Status: ${response.status}` }) throw new Error() } console.log(`Logado com sucesso. Checando Perfil...`) response.headers .get('set-cookie') .split(';') .forEach((data) => { if (data.includes('device') || data.includes('auth') || data.includes('saude') || data.includes('expires')) { cookiesArr.push(data) } }) cookiesFinal.Device = cookiesArr[0].split('device_id=')[1] cookiesFinal.Expires = cookiesArr[1].split('expires_in=')[1] cookiesFinal.Auth = cookiesArr[2].split('auth_token=')[1] cookiesFinal.VmxSession = cookiesArr[3].split('_vmx_saude_session=')[1] return cookiesFinal } catch (error) { return null } } const checkPerfil = async (cookies) => { const operadorID = atob(atob(decodeURIComponent(cookies.Auth.split('--')[0])).split('.')[1]).match(/"seg_operador_id"\s*:\s*(\d+)/)[1] try { const response = await fetch(`${baseUrl}.vivver.com/seg/operador.json?seg_operador%5Bid%5D=${operadorID}`, { method: 'GET', headers: { cookie: `device_id=${cookies.Device}; auth_token=${cookies.Auth}; expires_in=${cookies.Expires}; _vmx_saude_session=${cookies.VmxSession}`, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36', }, }) if (!response.ok) { console.log(`Falhou ao identificar o Perfil do Usuário logado: ${response.status}`) res.json({ errorCode: 2, errorMessage: `Falhou ao identificar o Perfil do Usuário logado: ${response.status}` }) throw new Error() } const perfilOperador = (await response.json()).data[0]['4'] if (perfilOperador.split(' - ')[1] === 'Administrador') { console.log(`Perfil Administrador. Consolidando os dados necessários da Base...`) res.status(200).json({ success: true }) } else { console.log(`Perfil do usuário logado não é Administrador. Perfil: ${perfilOperador}`) res.json({ errorCode: 3, errorMessage: `Perfil deve ser Administrador. Perfil: ${perfilOperador}` }) throw new Error() } } catch (error) { return null } } cookies = await loginVivver(adminCredentials.loginCookie, adminCredentials.senhaCookie) if (cookies) { await checkPerfil(cookies) } }) serverApp.get('/consolidar', async (req, res) => { const getUserDocuments = async (cookies) => { const dadosPessoais = {} try { const response = await fetch(`${baseUrl}.vivver.com/amb/paciente.json?start=0&length=9999999`, { method: 'GET', headers: { cookie: `device_id=${cookies.Device}; auth_token=${cookies.Auth}; expires_in=${cookies.Expires}; _vmx_saude_session=${cookies.VmxSession}`, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36', }, dispatcher: agent, keepalive: true, }) if (!response.ok) throw new Error(`Failed to fetch user documents: ${response.status}`) const data = (await response.json()).data data.forEach((dadoPessoal) => { dadosPessoais[`${dadoPessoal['0']}`] = { CPF: dadoPessoal['5'] || false, CNS: dadoPessoal['6'] || false, } }) return dadosPessoais } catch (error) { console.error(error) return null } } const getCnesUnidades = async (cookies) => { const unidadesCNES = {} try { const response = await fetch(`${baseUrl}.vivver.com/adm/unidade_saude.json?start=0&length=9999`, { method: 'GET', headers: { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', cookie: `device_id=${cookies.Device}; auth_token=${cookies.Auth}; expires_in=${cookies.Expires}; _vmx_saude_session=${cookies.VmxSession}`, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36', }, }) if (!response.ok) throw new Error(`Failed to fetch CNES units: ${response.status}`) const data = (await response.json()).data data.forEach((unidade) => { unidadesCNES[`${unidade['0']}|${unidade['1']}`] = { CNES: unidade['3'].toString().length >= 2 ? unidade['3'].toString() : adminCredentials.cnesRegulador, } }) return unidadesCNES } catch (error) { console.error(error) return null } } const getFaturaveis = async (cookies) => { const procFaturaveis = {} try { const response = await fetch( `${baseUrl}.vivver.com/fwk/lookup_edit_v3?page=1&limit=99999&model=Adm%3A%3AProcedimento&key=codprocedimentofaturavel&name=nomprocedimento&columns=codprocedimento%2Ccodprocedimento`, { method: 'GET', headers: { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', cookie: `device_id=${cookies.Device}; auth_token=${cookies.Auth}; expires_in=${cookies.Expires}; _vmx_saude_session=${cookies.VmxSession}`, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36', }, } ) if (!response.ok) throw new Error(`Failed to fetch billable procedures: ${response.status}`) const data = (await response.json()).rows data.forEach((procedimento) => { procFaturaveis[`${procedimento['codprocedimento']}`] = { procFaturavel: procedimento['codprocedimentofaturavel'] ? procedimento['codprocedimentofaturavel'].toString() : false, } }) return procFaturaveis } catch (error) { console.error(error) return null } } const getFilas = async (cookies) => { try { const response = await fetch(`${baseUrl}.vivver.com/rams/servico/solicitacao/acompanhamento/fila_espera.json`, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', cookie: `device_id=${cookies.Device}; auth_token=${cookies.Auth}; expires_in=${cookies.Expires}; _vmx_saude_session=${cookies.VmxSession}`, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36', }, body: 'offset=0&limit=100', dispatcher: agent, keepalive: true, }) if (!response.ok) throw new Error(`Failed to fetch waitlist requests: ${response.status}`) const finalData = (await response.json()).rows return finalData } catch (error) { console.error(error) return null } } try { //prettier-ignore [userData, cnesUnidades, procedimentosFaturaveis, solicitacoesEmFila] = await Promise.allSettled([getUserDocuments(cookies), getCnesUnidades(cookies), getFaturaveis(cookies), getFilas(cookies)]) const failedRequests = [] if (userData.status === 'rejected') failedRequests.push('Falhou ao pegar os Documentos dos usuários da Base') if (cnesUnidades.status === 'rejected') failedRequests.push('Falhou ao listar os CNES das Unidades da Base') if (procedimentosFaturaveis.status === 'rejected') failedRequests.push('Falhou ao listar os Procedimentos Faturáveis dos 99 da Base') if (solicitacoesEmFila.status === 'rejected') failedRequests.push('Falhou ao listar Solicitações em Fila de Espera da Base') if (failedRequests.length > 0) { return res.status(500).json({ errorCode: true, errorMessages: failedRequests, }) } res.status(200).json({ success: true }) } catch (error) { console.error(error) return null } }) serverApp.get('/gerar', async (req, res) => { const gerarXLSX = async (userData, solicitacoesEmFila, cnesUnidades, procedimentosFaturaveis) => { const dadosPrincipais = [] const usersSemDocumento = [] const solicitacoesSemFaturavel = [] const consultaSemCBOExecutante = [] solicitacoesEmFila.forEach((solicitacao) => { //Usuário sem CPF e sem CNS if (!userData[`${solicitacao.numprontuario.toString()}`]?.CPF && !userData[`${solicitacao.numprontuario.toString()}`]?.CNS) { usersSemDocumento.push({ Prontuário: solicitacao.numprontuario.toString(), Solicitação: solicitacao.amb_solicitacao_procedimento_servico_id.toString(), 'Unidade Solicitante': solicitacao.nome_unidade_solicitacao.toString() || '', 'Unidade Referência': solicitacao.nome_unidade_referencia.toString() || '', Telefone: solicitacao.telefone.toString() || '', }) return } solicitacao.fila_espera.forEach((itemSolicitacao) => { let conditionalFlag = false //Solicitação não possui um procedimento Faturável if (!procedimentosFaturaveis[`${itemSolicitacao.codigo_procedimento.toString()}`]?.procFaturavel) { solicitacoesSemFaturavel.push({ Prontuário: solicitacao.numprontuario.toString(), Solicitação: solicitacao.amb_solicitacao_procedimento_servico_id.toString(), 'Cód. Procedimento': itemSolicitacao.codigo_procedimento.toString() || '', 'Nome Procedimento': itemSolicitacao.nome_procedimento.toString() || '', 'Unidade Solicitante': solicitacao.nome_unidade_solicitacao.toString() || '', Serviço: solicitacao.servico_tipo_nome.toString().split(' - ')[1], }) conditionalFlag = true return } //Solicitação de Consulta* sem CBO Executante if (procedimentosFaturaveis[`${itemSolicitacao.codigo_procedimento.toString()}`].procFaturavel.toString().slice(0, 6) === '030101' && !itemSolicitacao.codigo_especialidade_executante) { consultaSemCBOExecutante.push({ Prontuário: solicitacao.numprontuario.toString(), Solicitação: solicitacao.amb_solicitacao_procedimento_servico_id.toString(), 'Cód. Procedimento': itemSolicitacao.codigo_procedimento.toString() || '', 'Nome Procedimento': itemSolicitacao.nome_procedimento.toString() || '', 'Procedimento Faturável': procedimentosFaturaveis[`${itemSolicitacao.codigo_procedimento.toString()}`].procFaturavel.toString() || '', Serviço: solicitacao.servico_tipo_nome.toString().split(' - ')[1], 'Unidade Solicitante': solicitacao.nome_unidade_solicitacao.toString() || '', }) conditionalFlag = true return } if (conditionalFlag) return dadosPrincipais.push({ identificador_local: solicitacao.amb_solicitacao_procedimento_servico_id.toString(), documento_paciente: validateCPF(userData[`${solicitacao.numprontuario.toString()}`].CPF) ? userData[`${solicitacao.numprontuario.toString()}`].CPF : userData[`${solicitacao.numprontuario.toString()}`].CNS, data_solicitacao: `${solicitacao.data_hora_solicitacao.split(' ')[0].split('/')[2]}-${solicitacao.data_hora_solicitacao.split(' ')[0].split('/')[1]}-${ solicitacao.data_hora_solicitacao.split(' ')[0].split('/')[0] }`, cnes_solicitante: cnesUnidades[`${solicitacao.codigo_municipio_solicitacao}|${solicitacao.codigo_unidade_solicitacao}`].CNES, cnes_regulador: adminCredentials.cnesRegulador, codigo_sigtap: procedimentosFaturaveis[`${itemSolicitacao.codigo_procedimento.toString()}`].procFaturavel, cbo: itemSolicitacao.codigo_especialidade_executante ? itemSolicitacao.codigo_especialidade_executante.toString() : '', cid10: itemSolicitacao.codigo_cid ? itemSolicitacao.codigo_cid.toString() : '', codigo_modalidade_assistencial: '07', codigo_carter_solicitacao: '1', status: '1', data_autorizacao: '', data_execucao: '', cnes_executante: '', }) }) }) console.log('Dados consolidados. Enviando para o Front-End...') res.status(200).json({ success: true, dados: [dadosPrincipais, usersSemDocumento, solicitacoesSemFaturavel, consultaSemCBOExecutante] }) } await gerarXLSX(userData.value, solicitacoesEmFila.value, cnesUnidades.value, procedimentosFaturaveis.value) console.log('Finalizado.') }) function startExpressServer() { serverApp.listen(port, () => { console.log(`Server running at http://localhost:${port}`) }) } let mainWindow if (started) { app.quit() } app.whenReady().then(() => { startExpressServer() const { width, height } = screen.getPrimaryDisplay().workAreaSize // Get screen height and width const windowWidth = width * 0.8 const windowHeight = windowWidth * (9 / 16) mainWindow = new BrowserWindow({ width: windowWidth, height: windowHeight, webPreferences: { nodeIntegration: true, contextIsolation: false, }, }) mainWindow.loadURL(`http://localhost:${port}`) mainWindow.on('closed', () => { mainWindow = null }) }) app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } })