Compare commits
No commits in common. "7e448aaed10e6209db8d33cb61db767247d6887b" and "e78d2e2b8c7213ea0ce67fe88d7a0990d2822ba1" have entirely different histories.
7e448aaed1
...
e78d2e2b8c
109
index.html
109
index.html
File diff suppressed because one or more lines are too long
116
package-lock.json
generated
Normal file
116
package-lock.json
generated
Normal file
@ -0,0 +1,116 @@
|
||||
{
|
||||
"name": "pdz-report",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "pdz-report",
|
||||
"dependencies": {
|
||||
"xlsx": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/adler-32": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
|
||||
"integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/cfb": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
|
||||
"integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"adler-32": "~1.3.0",
|
||||
"crc-32": "~1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/codepage": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
|
||||
"integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/crc-32": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
|
||||
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"crc32": "bin/crc32.njs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/frac": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
|
||||
"integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/ssf": {
|
||||
"version": "0.11.2",
|
||||
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
|
||||
"integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"frac": "~1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/wmf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
|
||||
"integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/word": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
|
||||
"integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/xlsx": {
|
||||
"version": "0.18.5",
|
||||
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
|
||||
"integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"adler-32": "~1.3.0",
|
||||
"cfb": "~1.2.1",
|
||||
"codepage": "~1.15.0",
|
||||
"crc-32": "~1.2.1",
|
||||
"ssf": "~0.11.2",
|
||||
"wmf": "~1.0.1",
|
||||
"word": "~0.3.0"
|
||||
},
|
||||
"bin": {
|
||||
"xlsx": "bin/xlsx.njs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
package.json
Normal file
11
package.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "pdz-report",
|
||||
"private": true,
|
||||
"type": "commonjs",
|
||||
"dependencies": {
|
||||
"xlsx": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node server.js"
|
||||
}
|
||||
}
|
||||
78
server.js
Normal file
78
server.js
Normal file
@ -0,0 +1,78 @@
|
||||
const http = require("http");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const XLSX = require("xlsx");
|
||||
|
||||
const PORT = process.env.PORT || 3000;
|
||||
const DATA_FILE = path.join(__dirname, "123-1.xlsx");
|
||||
|
||||
let cachedData = null;
|
||||
|
||||
function loadData() {
|
||||
if (cachedData) return cachedData;
|
||||
try {
|
||||
const wb = XLSX.readFile(DATA_FILE);
|
||||
const ws = wb.Sheets["Проблемная B2G июнь"];
|
||||
const rows = XLSX.utils.sheet_to_json(ws);
|
||||
cachedData = rows.map(r => ({
|
||||
"Регион": r["Регион"] || "",
|
||||
"Сервер": r["Сервер"] || "",
|
||||
"Район": r["Район CRM"] || "",
|
||||
"Город": r["Город"] || "",
|
||||
"Адрес": r["Адрес CRM"] || "",
|
||||
"Сегмент": r["Сегмент"] || "",
|
||||
"Категория": r["Категория"] || "",
|
||||
"Лицевой счет": r["Лицевой счет"] || "",
|
||||
"Абонент": r["Абонент"] || "",
|
||||
"БИН": r["БИН/ИИН"] || "",
|
||||
"Контракт": r["номер контракта crm"] || "",
|
||||
"Начало": r["начало действия crm"] || "",
|
||||
"Конец": r["Макс дата образования ДЗ"] || "",
|
||||
"ДЗ итого": r["Дебиторская задолженность(Итого)"] || 0,
|
||||
"ПДЗ": r["ПДЗ"] || 0,
|
||||
"ИТОГО ПДЗ": r["ИТОГО ПДЗ на 01.06.2026"] || r["ИТОГО ПДЗ"] || 0,
|
||||
"ЛС CRM": r["ЛС CRM 2.0"] || "",
|
||||
"Менеджер": r["персональный менеджер"] || "",
|
||||
"Период": r["период внесения"] || "",
|
||||
"Статус С/Д": r["С/Д июнь"] || r["С/Д май"] || "",
|
||||
"Статус": r["Статусы июнь"] || r["Статусы май"] || "",
|
||||
"Отработка": r["Текущий статус июнь"] || r["Текущий статус май"] || "",
|
||||
"Причина": r["Причина июнь"] || r["Причина май"] || "",
|
||||
"Ход работы": r["Ход работы июнь"] || "",
|
||||
"Сотрудник": r["Сотрудник"] || ""
|
||||
})).filter(r => r["Абонент"] && r["Лицевой счет"]);
|
||||
return cachedData;
|
||||
} catch (e) {
|
||||
console.error("Ошибка загрузки данных:", e.message);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function body(req) {
|
||||
return new Promise((resolve) => {
|
||||
let s = "";
|
||||
req.on("data", (c) => (s += c));
|
||||
req.on("end", () => { try { resolve(JSON.parse(s || "{}")); } catch (_) { resolve({}); } });
|
||||
});
|
||||
}
|
||||
|
||||
http.createServer(async (req, res) => {
|
||||
if (req.method === "GET" && req.url === "/api/data") {
|
||||
const data = loadData();
|
||||
res.writeHead(200, {
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Access-Control-Allow-Origin": "*"
|
||||
});
|
||||
return res.end(JSON.stringify(data));
|
||||
}
|
||||
|
||||
let file = req.url === "/" ? "/index.html" : req.url.split("?")[0];
|
||||
const full = path.join(__dirname, file);
|
||||
if (full.startsWith(__dirname) && fs.existsSync(full) && fs.statSync(full).isFile()) {
|
||||
const ext = path.extname(full);
|
||||
const type = ext === ".css" ? "text/css" : ext === ".js" ? "application/javascript" : ext === ".json" ? "application/json" : "text/html";
|
||||
res.writeHead(200, { "Content-Type": type + "; charset=utf-8" });
|
||||
return res.end(fs.readFileSync(full));
|
||||
}
|
||||
res.writeHead(404); res.end("Not found");
|
||||
}).listen(PORT, () => console.log("Сервер запущен на порту " + PORT));
|
||||
Loading…
Reference in New Issue
Block a user