Files
Aislo/tools/est-test/search-store.cjs
T
eomsangdonandClaude Opus 5.5 5b2ebeb676 feat(est-test): 저장된 작업 통합 검색과 가져오기
- 원본 통합 검색처럼 자료 7종을 검색어로 찾고 하위 연결째 현재 공사로 가져옴

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 19:43:15 +09:00

70 lines
2.3 KiB
JavaScript

// 원본 통합 검색(TFRMMULTISERCH: 일위대가·단가산출·기계경비·견적·실적·자재·노임 고르기, 검색어, 검색위치) —
// 웹은 이 앱에 저장된 작업(data/*.json)을 검색 위치로 쓴다. 검색어 낱말이 모두 코드·품명·규격에 들어 있으면 찾음.
const fs = require("node:fs");
const path = require("node:path");
const sources = {
103: ["HeadTitleDat", "일위대가"],
104: ["CostTitleDat", "단가산출"],
105: ["MachTitleDat", "기계경비"],
101: ["EstiMateDat", "견적단가"],
21: ["SilJukDat", "실적단가"],
5: ["StuffcDat", "자재단가"],
6: ["LaborcDat", "노임단가"],
};
const LIMIT = 300;
const fold = (value) =>
String(value ?? "")
.normalize("NFKC")
.toLowerCase()
.replace(/\s+/g, "");
function search(directory, query, kinds, exclude = "") {
const words = String(query ?? "")
.split(/\s+/)
.map(fold)
.filter(Boolean);
if (!words.length) throw Error("검색어를 입력하세요.");
const wanted = (kinds?.length ? kinds : Object.keys(sources))
.map(Number)
.filter((k) => sources[k]);
if (!wanted.length) throw Error("검색할 자료를 하나 이상 고르세요.");
if (!fs.existsSync(directory)) return { hits: [], total: 0 };
const hits = [];
let total = 0;
for (const name of fs.readdirSync(directory).filter((n) => /^[a-f0-9]{24}\.json$/.test(n))) {
const id = name.slice(0, -5);
if (id === exclude) continue;
let project;
try {
project = JSON.parse(fs.readFileSync(path.join(directory, name), "utf8"));
} catch {
continue;
}
for (const kind of wanted) {
const [table, label] = sources[kind];
for (const row of project.tables?.[table] || []) {
if (!row?.Code) continue;
const text = fold(`${row.Code} ${row.Name} ${row.Size}`);
if (!words.every((w) => text.includes(w))) continue;
total++;
if (hits.length < LIMIT)
hits.push({
id,
project: project.name || id,
kind,
label,
Code: row.Code,
Name: row.Name ?? "",
Size: row.Size ?? "",
Unite: row.Unite ?? "",
price: Number(row.TC) || 0,
});
}
}
}
return { hits, total };
}
module.exports = { search, sources };