95 lines
3.0 KiB
JavaScript
95 lines
3.0 KiB
JavaScript
/**
|
||
* Разбор файла (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);
|