163 lines
6.2 KiB
JavaScript
163 lines
6.2 KiB
JavaScript
const http = require("http");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const formidable = require("formidable");
|
|
|
|
const PORT = process.env.PORT || 3000;
|
|
const DATA = path.join(__dirname, "data.json");
|
|
const UPLOADS = path.join(__dirname, "uploads");
|
|
|
|
if (!fs.existsSync(UPLOADS)) fs.mkdirSync(UPLOADS);
|
|
|
|
function readData() {
|
|
try { return JSON.parse(fs.readFileSync(DATA, "utf8")); } catch (_) { return { inputData: null, suppliers: [], offers: [], checks: { c1: false, c2: false, c3: false }, files: [] }; }
|
|
}
|
|
function writeData(data) {
|
|
fs.writeFileSync(DATA, JSON.stringify(data, null, 2));
|
|
}
|
|
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") {
|
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
return res.end(JSON.stringify(readData()));
|
|
}
|
|
|
|
if (req.method === "GET" && req.url === "/api/files") {
|
|
const data = readData();
|
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
return res.end(JSON.stringify(data.files || []));
|
|
}
|
|
|
|
if (req.method === "POST" && req.url === "/api/upload") {
|
|
const form = formidable({ uploadDir: UPLOADS, keepExtensions: true });
|
|
form.parse(req, async (err, fields, files) => {
|
|
if (err) {
|
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
return res.end(JSON.stringify({ error: err.message }));
|
|
}
|
|
const data = readData();
|
|
const uploaded = [];
|
|
if (files.file && Array.isArray(files.file)) {
|
|
for (const f of files.file) {
|
|
const fileName = Date.now() + "_" + path.basename(f.filepath);
|
|
const newPath = path.join(UPLOADS, fileName);
|
|
fs.renameSync(f.filepath, newPath);
|
|
const fileRec = {
|
|
id: Date.now() + Math.random(),
|
|
name: f.originalFilename || fileName,
|
|
path: "/api/files/" + fileName,
|
|
section: fields.section ? fields.section[0] : "other",
|
|
size: f.size,
|
|
date: new Date().toISOString()
|
|
};
|
|
data.files.push(fileRec);
|
|
uploaded.push(fileRec);
|
|
}
|
|
}
|
|
writeData(data);
|
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
return res.end(JSON.stringify({ ok: true, files: uploaded }));
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (req.method === "GET" && req.url.startsWith("/api/files/")) {
|
|
const fileName = req.url.split("/")[3];
|
|
const filePath = path.join(UPLOADS, fileName);
|
|
if (fs.existsSync(filePath)) {
|
|
const ext = path.extname(fileName).toLowerCase();
|
|
const mime = ext === ".pdf" ? "application/pdf" : ext === ".docx" ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : ext === ".xlsx" ? "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" : "application/octet-stream";
|
|
res.writeHead(200, { "Content-Type": mime, "Content-Disposition": "attachment; filename=\"" + fileName + "\"" });
|
|
return res.end(fs.readFileSync(filePath));
|
|
}
|
|
res.writeHead(404); res.end("File not found");
|
|
return;
|
|
}
|
|
|
|
if (req.method === "DELETE" && req.url.startsWith("/api/files/")) {
|
|
const fileName = req.url.split("/")[3];
|
|
const data = readData();
|
|
const fileRec = data.files.find(f => f.path.endsWith(fileName));
|
|
if (fileRec) {
|
|
const filePath = path.join(UPLOADS, fileName);
|
|
if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
|
|
data.files = data.files.filter(f => f.path !== fileRec.path);
|
|
writeData(data);
|
|
}
|
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
return res.end(JSON.stringify({ ok: true }));
|
|
}
|
|
|
|
if (req.method === "POST" && req.url === "/api/inputData") {
|
|
const d = await body(req);
|
|
const data = readData();
|
|
data.inputData = d;
|
|
writeData(data);
|
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
return res.end(JSON.stringify({ ok: true }));
|
|
}
|
|
|
|
if (req.method === "POST" && req.url === "/api/suppliers") {
|
|
const s = await body(req);
|
|
const data = readData();
|
|
data.suppliers.push({ id: Date.now(), ...s });
|
|
writeData(data);
|
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
return res.end(JSON.stringify({ ok: true }));
|
|
}
|
|
|
|
if (req.method === "POST" && req.url === "/api/offers") {
|
|
const o = await body(req);
|
|
const data = readData();
|
|
data.offers.push({ id: Date.now(), ...o });
|
|
writeData(data);
|
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
return res.end(JSON.stringify({ ok: true }));
|
|
}
|
|
|
|
if (req.method === "POST" && req.url === "/api/checks") {
|
|
const c = await body(req);
|
|
const data = readData();
|
|
data.checks = c;
|
|
writeData(data);
|
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
return res.end(JSON.stringify({ ok: true }));
|
|
}
|
|
|
|
if (req.method === "DELETE" && req.url.startsWith("/api/suppliers/")) {
|
|
const id = parseInt(req.url.split("/")[3]);
|
|
const data = readData();
|
|
data.suppliers = data.suppliers.filter(s => s.id !== id);
|
|
data.offers = data.offers.filter(o => o.supplierId !== id);
|
|
writeData(data);
|
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
return res.end(JSON.stringify({ ok: true }));
|
|
}
|
|
|
|
if (req.method === "DELETE" && req.url.startsWith("/api/offers/")) {
|
|
const id = parseInt(req.url.split("/")[3]);
|
|
const data = readData();
|
|
data.offers = data.offers.filter(o => o.id !== id);
|
|
writeData(data);
|
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
return res.end(JSON.stringify({ ok: true }));
|
|
}
|
|
|
|
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" : "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));
|