Feature: отдельная страница data.html, общие css и upload-core.js
Made-with: Cursor
This commit is contained in:
94
js/upload-core.js
Normal file
94
js/upload-core.js
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Разбор файла (CSV / JSON / Excel) и синхронизация с API.
|
||||
* Зависимости: глобальные Papa, XLSX (CDN на странице).
|
||||
*/
|
||||
(function (global) {
|
||||
function parseExcelToRows(buffer) {
|
||||
if (typeof XLSX === "undefined") {
|
||||
throw new Error("Библиотека Excel не загружена (XLSX). Проверьте сеть и CDN.");
|
||||
}
|
||||
const wb = XLSX.read(buffer, { type: "array" });
|
||||
if (!wb.SheetNames || !wb.SheetNames.length) {
|
||||
throw new Error("В книге Excel нет листов");
|
||||
}
|
||||
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||
return XLSX.utils.sheet_to_json(ws, {
|
||||
defval: "",
|
||||
raw: false,
|
||||
blankrows: false
|
||||
});
|
||||
}
|
||||
|
||||
function parseFileToRows(file) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const lower = file.name.toLowerCase();
|
||||
const isExcel = lower.endsWith(".xlsx") || lower.endsWith(".xls");
|
||||
if (isExcel) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (ev) {
|
||||
try {
|
||||
resolve(parseExcelToRows(new Uint8Array(ev.target.result)));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
};
|
||||
reader.onerror = function () {
|
||||
reject(new Error("Не удалось прочитать файл"));
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
return;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (ev) {
|
||||
try {
|
||||
const text = String(ev.target.result || "");
|
||||
let rows;
|
||||
if (lower.endsWith(".json")) {
|
||||
const data = JSON.parse(text);
|
||||
if (!Array.isArray(data)) throw new Error("JSON должен быть массивом объектов");
|
||||
rows = data;
|
||||
} else {
|
||||
const parsed = Papa.parse(text, { header: true, skipEmptyLines: true });
|
||||
if (parsed.errors && parsed.errors.length) console.warn(parsed.errors);
|
||||
rows = parsed.data || [];
|
||||
}
|
||||
resolve(rows);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
};
|
||||
reader.onerror = function () {
|
||||
reject(new Error("Не удалось прочитать файл"));
|
||||
};
|
||||
reader.readAsText(file, "UTF-8");
|
||||
});
|
||||
}
|
||||
|
||||
function syncRowsToServer(rows) {
|
||||
return fetch("/api/incidents/sync", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ rows: rows })
|
||||
}).then(function (r) {
|
||||
if (!r.ok) {
|
||||
return r.text().then(function (t) {
|
||||
throw new Error(t || "HTTP " + r.status);
|
||||
});
|
||||
}
|
||||
return r.json();
|
||||
});
|
||||
}
|
||||
|
||||
function fetchIncidents() {
|
||||
return fetch("/api/incidents").then(function (r) {
|
||||
if (!r.ok) return null;
|
||||
return r.json();
|
||||
});
|
||||
}
|
||||
|
||||
global.OmcUpload = {
|
||||
parseFileToRows: parseFileToRows,
|
||||
syncRowsToServer: syncRowsToServer,
|
||||
fetchIncidents: fetchIncidents
|
||||
};
|
||||
})(typeof window !== "undefined" ? window : this);
|
||||
Reference in New Issue
Block a user