FEAT: Adiciona novo arquivo de modelo para análise de viabilidade por geolocalização e disponibiliza para download ao clicar em "Baixar Modelos". Pequenas alterações nos textos do front-end.

This commit is contained in:
tulioperdigao 2025-11-10 14:38:01 -03:00
parent f28ad3a716
commit 3942864554
5 changed files with 6009 additions and 12 deletions

20
app.js
View File

@ -464,12 +464,24 @@ function createApp() {
});
// download model endpoint
app.get("/download-model", (req, res) => {
const modelPath = path.join(__dirname, "models", "modelo.viabilidade.csv");
if (!fs.existsSync(modelPath)) return res.status(404).send("Modelo não encontrado");
return res.download(modelPath, "modelo.viabilidade.csv");
app.get("/download-model/:name", (req, res) => {
const name = req.params.name;
const safeName = path.basename(name); // evita ../
const filePath = path.join(__dirname, "models", safeName);
if (!fs.existsSync(filePath)) return res.status(404).send("Arquivo não encontrado");
return res.download(filePath, safeName);
});
// lista os arquivos disponíveis em /models
app.get("/download-models/list", (req, res) => {
const modelDir = path.join(__dirname, "models");
if (!fs.existsSync(modelDir)) return res.status(404).json({ error: "Pasta de modelos não encontrada" });
const files = fs.readdirSync(modelDir).filter((f) => fs.statSync(path.join(modelDir, f)).isFile());
return res.json({ files });
});
// download result endpoint
app.get("/download/:name", (req, res) => {
const name = req.params.name;

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@
<div class="card-body">
<h5>Consulta em lote:</h5>
<p>
Faça um upload de um arquivo .CSV com a primeira coluna com os CEPs e a segunda coluna com o número do logradouro. O resultado da consulta será baixado automaticamente em um arquivo .CSV em seu computador. Caso precise baixar o modelo de arquivo para upload, clique em baixar modelo.
Faça um upload de um arquivo .CSV com a primeira coluna com os CEPs e a segunda coluna com o número do logradouro. O resultado da consulta será baixado automaticamente em um arquivo .CSV em seu computador. Caso precise baixar os modelos de arquivo para upload, clique em "Baixar Modelos".
</p>
<form id="uploadForm">
<div class="mb-3">
@ -45,7 +45,7 @@
</div>
<div class="card-buttons__container">
<button class="btn btn-primary button-mobile" type="submit">Enviar CSV</button>
<button type="button" class="btn btn-primary button-mobile" id="card__button-download">Baixar Modelo</button>
<button type="button" class="btn btn-primary button-mobile" id="card__button-download">Baixar Modelos</button>
</div>
</form>
<div id="uploadResult" class="mt-3"></div>

View File

@ -69,10 +69,38 @@ document.getElementById('btnConsultaCep').addEventListener('click', async () =>
});
// baixar modelo
const modelBtn = document.getElementById('card__button-download');
if (modelBtn) {
modelBtn.addEventListener('click', (e) => {
// inicia download do endpoint que serve o modelo
window.location.href = '/download-model';
// botão que inicia download de todos os modelos individualmente
document.addEventListener("DOMContentLoaded", () => {
const btn = document.getElementById("card__button-download");
if (!btn) return;
btn.addEventListener("click", async (e) => {
e.preventDefault();
try {
const resp = await fetch("/download-models/list");
if (!resp.ok) throw new Error("Não foi possível obter lista de modelos");
const data = await resp.json();
const files = data.files || [];
if (!files.length) {
alert("Nenhum arquivo de modelo disponível");
return;
}
// Para cada arquivo, cria um <a> e clica nele para iniciar download individual
files.forEach((fname) => {
const url = "/download-model/" + encodeURIComponent(fname);
const a = document.createElement("a");
a.href = url;
a.download = fname;
// necessário anexar no DOM para funcionar em alguns navegadores
document.body.appendChild(a);
a.click();
a.remove();
});
} catch (err) {
console.error("Erro ao baixar modelos:", err);
alert("Erro ao iniciar downloads: " + (err.message || err));
}
});
}
});