Add utils.js with Excel reading, validation and normalization functions
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
// utils.js
|
||||
// Вспомогательные функции для работы с Excel, валидации и нормализации данных
|
||||
|
||||
/**
|
||||
* Читает файл Excel и возвращает массив листов.
|
||||
* @param {File} file
|
||||
* @returns {Promise<Array<{name:string, data:Array<Array<any>>}>>}
|
||||
*/
|
||||
export async function readExcel(file) {
|
||||
const data = await file.arrayBuffer();
|
||||
const wb = XLSX.read(data, { type: 'array' });
|
||||
return wb.SheetNames.map(name => ({
|
||||
name,
|
||||
data: XLSX.utils.sheet_to_json(wb.Sheets[name], { header: 1, defval: '' })
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка типа и размера файла.
|
||||
* @param {File} file
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function validateFile(file) {
|
||||
const ext = file.name.slice(file.name.lastIndexOf('.')).toLowerCase();
|
||||
if (!['.xlsx', '.xls'].includes(ext)) {
|
||||
alert(`Недопустимый тип файла: ${ext}`);
|
||||
return false;
|
||||
}
|
||||
if (file.size === 0) {
|
||||
alert('Файл пустой');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Нормализация номера ТС (замена латинских букв их русскими аналогами).
|
||||
* @param {string} plate
|
||||
* @returns {string}
|
||||
*/
|
||||
export function normalizePlate(plate) {
|
||||
const map = {A:'\u0410',B:'\u0412',C:'\u0421',E:'\u0415',H:'\u041D',K:'\u041A',M:'\u041C',O:'\u041E',P:'\u0420',T:'\u0422',X:'\u0425',Y:'\u0423'};
|
||||
return plate.toUpperCase().replace(/[ABCEHKMOPTXY]/g, ch => map[ch] || ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Приведение ФИО к единому регистру, замена Ё на Е.
|
||||
* @param {string} name
|
||||
* @returns {string}
|
||||
*/
|
||||
export function normalizeName(name) {
|
||||
return name.toUpperCase().replace(/\u0401/g, '\u0415').trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Вычисление схожести строк (Levenshtein).
|
||||
* @param {string} a
|
||||
* @param {string} b
|
||||
* @returns {number} коэффициент от 0 до 1
|
||||
*/
|
||||
export function similarity(a, b) {
|
||||
if (!a || !b) return 0;
|
||||
const editDist = (s1, s2) => {
|
||||
const dp = Array(s1.length + 1).fill().map(() => Array(s2.length + 1).fill(0));
|
||||
for (let i = 0; i <= s1.length; i++) dp[i][0] = i;
|
||||
for (let j = 0; j <= s2.length; j++) dp[0][j] = j;
|
||||
for (let i = 1; i <= s1.length; i++) {
|
||||
for (let j = 1; j <= s2.length; j++) {
|
||||
dp[i][j] = s1[i - 1] === s2[j - 1]
|
||||
? dp[i - 1][j - 1]
|
||||
: Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1;
|
||||
}
|
||||
}
|
||||
return dp[s1.length][s2.length];
|
||||
};
|
||||
const dist = editDist(a, b);
|
||||
return 1 - dist / Math.max(a.length, b.length);
|
||||
}
|
||||
Reference in New Issue
Block a user