povrezhdenie-po-stpk-avtomat/server.js

108 lines
3.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const http = require("http");
const fs = require("fs");
const path = require("path");
const PORT = process.env.PORT || 3000;
const DATA = path.join(__dirname, "data.json");
function readData() {
try { return JSON.parse(fs.readFileSync(DATA, "utf8")); } catch (_) { return { items: [], log: [] }; }
}
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) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
if (req.method === "OPTIONS") {
res.writeHead(200);
return res.end();
}
const url = req.url.split("?")[0];
// API: список заявок
if (req.method === "GET" && url === "/api/items") {
res.writeHead(200, { "Content-Type": "application/json" });
return res.end(JSON.stringify(readData().items));
}
// API: добавить заявку
if (req.method === "POST" && url === "/api/items") {
const item = await body(req);
const data = readData();
const newItem = {
id: Date.now(),
createdAt: new Date().toISOString(),
status: "новая",
...item
};
data.items.push(newItem);
data.log.push({ when: new Date().toISOString(), what: "Добавлена заявка #" + newItem.id, who: item.person || "anon" });
writeData(data);
res.writeHead(200, { "Content-Type": "application/json" });
return res.end(JSON.stringify({ ok: true, item: newItem }));
}
// API: обновить заявку
if (req.method === "PUT" && url.startsWith("/api/items/")) {
const id = parseInt(url.split("/")[3]);
const updates = await body(req);
const data = readData();
const idx = data.items.findIndex(i => i.id === id);
if (idx !== -1) {
const old = data.items[idx];
data.items[idx] = { ...old, ...updates };
data.log.push({ when: new Date().toISOString(), what: "Изменена заявка #" + id, who: updates.person || "anon" });
writeData(data);
res.writeHead(200, { "Content-Type": "application/json" });
return res.end(JSON.stringify({ ok: true }));
}
res.writeHead(404);
return res.end(JSON.stringify({ error: "Не найдено" }));
}
// API: удалить заявку
if (req.method === "DELETE" && url.startsWith("/api/items/")) {
const id = parseInt(url.split("/")[3]);
const data = readData();
const item = data.items.find(i => i.id === id);
data.items = data.items.filter(i => i.id !== id);
if (item) {
data.log.push({ when: new Date().toISOString(), what: "Удалена заявка #" + id + " (" + item.object + ")", who: "system" });
}
writeData(data);
res.writeHead(200, { "Content-Type": "application/json" });
return res.end(JSON.stringify({ ok: true }));
}
// API: лог действий
if (req.method === "GET" && url === "/api/log") {
res.writeHead(200, { "Content-Type": "application/json" });
return res.end(JSON.stringify(readData().log.slice(-50)));
}
// Статика
let file = url === "/" ? "/index.html" : url;
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));