Update search.js
This commit is contained in:
+184
-52
@@ -1,76 +1,208 @@
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const readline = require("readline");
|
||||
let documents = [];
|
||||
|
||||
const filePath = path.join(__dirname, "SadenTel_Documents.csv");
|
||||
const searchInput = document.getElementById("searchInput");
|
||||
const results = document.getElementById("results");
|
||||
const status = document.getElementById("status");
|
||||
|
||||
// خواندن فایل CSV
|
||||
const fileContent = fs.readFileSync(filePath, "utf8");
|
||||
// لینک مستقیم فایل CSV در مخزن Git
|
||||
const CSV_URL = "https://git.sadentel.net/f.taghipour/Document/raw/branch/main/SadenTel_Documents.csv";
|
||||
|
||||
// تبدیل CSV به آرایه اسناد
|
||||
const lines = fileContent.trim().split(/\r?\n/);
|
||||
|
||||
const documents = lines.slice(1).map(line => {
|
||||
const columns = line.split(",");
|
||||
// یکسانسازی حروف و اعداد
|
||||
function normalize(value) {
|
||||
return String(value ?? "")
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/[۰-۹]/g, digit =>
|
||||
"۰۱۲۳۴۵۶۷۸۹".indexOf(digit)
|
||||
)
|
||||
.replace(/[٠-٩]/g, digit =>
|
||||
"٠١٢٣٤٥٦٧٨٩".indexOf(digit)
|
||||
)
|
||||
.replace(/ي/g, "ی")
|
||||
.replace(/ك/g, "ک");
|
||||
}
|
||||
|
||||
return {
|
||||
row: columns[0],
|
||||
title: columns[1],
|
||||
id: columns[2]
|
||||
};
|
||||
});
|
||||
|
||||
// ایجاد محیط دریافت ورودی
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
// پردازش فایل CSV
|
||||
function parseCSV(text) {
|
||||
const rows = [];
|
||||
let row = [];
|
||||
let field = "";
|
||||
let insideQuotes = false;
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
const char = text[i];
|
||||
|
||||
if (char === '"') {
|
||||
if (insideQuotes && text[i + 1] === '"') {
|
||||
field += '"';
|
||||
i++;
|
||||
} else {
|
||||
insideQuotes = !insideQuotes;
|
||||
}
|
||||
}
|
||||
|
||||
else if (char === "," && !insideQuotes) {
|
||||
row.push(field);
|
||||
field = "";
|
||||
}
|
||||
|
||||
else if (
|
||||
(char === "\n" || char === "\r") &&
|
||||
!insideQuotes
|
||||
) {
|
||||
if (char === "\r" && text[i + 1] === "\n") {
|
||||
i++;
|
||||
}
|
||||
|
||||
row.push(field);
|
||||
|
||||
if (row.some(value => value.trim() !== "")) {
|
||||
rows.push(row);
|
||||
}
|
||||
|
||||
row = [];
|
||||
field = "";
|
||||
}
|
||||
|
||||
else {
|
||||
field += char;
|
||||
}
|
||||
}
|
||||
|
||||
row.push(field);
|
||||
|
||||
if (row.some(value => value.trim() !== "")) {
|
||||
rows.push(row);
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
|
||||
// دریافت اطلاعات از لینک آنلاین CSV
|
||||
async function loadDocuments() {
|
||||
try {
|
||||
searchInput.disabled = true;
|
||||
|
||||
status.textContent = "در حال دریافت اسناد...";
|
||||
|
||||
const response = await fetch(CSV_URL, {
|
||||
cache: "no-store"
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("CSV file could not be loaded");
|
||||
}
|
||||
|
||||
const text = await response.text();
|
||||
|
||||
const rows = parseCSV(text);
|
||||
|
||||
documents = rows.slice(1).map(columns => ({
|
||||
row: columns[0]?.trim(),
|
||||
title: columns[1]?.trim(),
|
||||
id: columns[2]?.trim()
|
||||
})).filter(doc => doc.title && doc.id);
|
||||
|
||||
status.textContent =
|
||||
`${documents.length} سند با موفقیت بارگذاری شد.`;
|
||||
|
||||
searchInput.disabled = false;
|
||||
|
||||
} catch (error) {
|
||||
|
||||
status.textContent =
|
||||
"خطا در دریافت اطلاعات. دسترسی به فایل CSV را بررسی کنید.";
|
||||
|
||||
console.error("Loading error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// جستوجوی اسناد
|
||||
function searchDocument(query) {
|
||||
const searchText = query.trim().toLowerCase();
|
||||
function searchDocuments() {
|
||||
|
||||
const results = documents.filter(doc =>
|
||||
doc.title.toLowerCase().includes(searchText) ||
|
||||
doc.id.toLowerCase().includes(searchText)
|
||||
);
|
||||
const query = normalize(searchInput.value);
|
||||
|
||||
if (results.length === 0) {
|
||||
console.log("\nسندی پیدا نشد.");
|
||||
results.innerHTML = "";
|
||||
|
||||
if (!query) {
|
||||
status.textContent =
|
||||
`${documents.length} سند ثبت شده است.`;
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`\nتعداد نتایج: ${results.length}\n`);
|
||||
const matches = documents.filter(doc => {
|
||||
|
||||
results.forEach(doc => {
|
||||
console.log("------------------------------");
|
||||
console.log("عنوان سند:", doc.title);
|
||||
console.log("شناسه داخلی:", doc.id);
|
||||
console.log("ردیف:", doc.row);
|
||||
const title = normalize(doc.title);
|
||||
const id = normalize(doc.id);
|
||||
|
||||
// استخراج کلمات کامل عنوان
|
||||
const titleWords =
|
||||
title.match(/[\p{L}\p{N}]+/gu) || [];
|
||||
|
||||
// تطابق کامل کلمه یا شناسه
|
||||
return titleWords.includes(query) || id === query;
|
||||
});
|
||||
|
||||
console.log("------------------------------");
|
||||
}
|
||||
console.log("Search query:", query);
|
||||
console.table(matches);
|
||||
|
||||
// دریافت عبارت جستوجو
|
||||
function askSearch() {
|
||||
rl.question("\nنام یا شناسه سند را وارد کنید (برای خروج exit): ", query => {
|
||||
status.textContent =
|
||||
`${matches.length} نتیجه پیدا شد.`;
|
||||
|
||||
if (query.trim().toLowerCase() === "exit") {
|
||||
rl.close();
|
||||
return;
|
||||
}
|
||||
if (matches.length === 0) {
|
||||
|
||||
if (query.trim() === "") {
|
||||
console.log("لطفاً عبارت جستوجو را وارد کنید.");
|
||||
} else {
|
||||
searchDocument(query);
|
||||
}
|
||||
results.innerHTML =
|
||||
'<div class="empty">سندی با این مشخصات پیدا نشد.</div>';
|
||||
|
||||
askSearch();
|
||||
return;
|
||||
}
|
||||
|
||||
// نمایش نتایج
|
||||
matches.forEach(doc => {
|
||||
|
||||
const item = document.createElement("div");
|
||||
item.className = "result";
|
||||
|
||||
const title = document.createElement("h3");
|
||||
title.textContent = doc.title;
|
||||
|
||||
const rowInfo = document.createElement("div");
|
||||
rowInfo.className = "info";
|
||||
|
||||
const rowLabel = document.createElement("span");
|
||||
rowLabel.textContent = "ردیف";
|
||||
|
||||
const rowValue = document.createElement("span");
|
||||
rowValue.textContent = doc.row;
|
||||
|
||||
rowInfo.append(rowLabel, rowValue);
|
||||
|
||||
const idInfo = document.createElement("div");
|
||||
idInfo.className = "info";
|
||||
|
||||
const idLabel = document.createElement("span");
|
||||
idLabel.textContent = "شناسه داخلی سند";
|
||||
|
||||
const idValue = document.createElement("span");
|
||||
idValue.textContent = doc.id;
|
||||
|
||||
idInfo.append(idLabel, idValue);
|
||||
|
||||
item.append(title, rowInfo, idInfo);
|
||||
|
||||
results.appendChild(item);
|
||||
});
|
||||
}
|
||||
|
||||
console.log("===== SadenTel Document Search =====");
|
||||
askSearch();
|
||||
|
||||
// جستوجوی لحظهای
|
||||
searchInput.addEventListener("input", searchDocuments);
|
||||
|
||||
|
||||
// بارگذاری اولیه اطلاعات
|
||||
loadDocuments();
|
||||
|
||||
مرجع در شماره جدید
مسدود کردن کاربر