feat: 支持拼音搜索
All checks were successful
deploy to server / build-and-deploy (push) Successful in 3m38s

- 使用pinyin-pro进行汉语拼音转换
- 调整搜索权重
This commit is contained in:
2025-11-10 15:39:47 +08:00
parent 4c8dfb5b56
commit 710a0cdc5b
6 changed files with 71 additions and 4 deletions

View File

@ -41,8 +41,30 @@ export function fuzzyMatch<T extends object>(
});
// --- 文本标准化函数 ---
const normalizeText = (text: string): string =>
text.normalize('NFKC').toLowerCase().trim();
const normalizeText = (text: string): string => {
const normalizedText = text.normalize('NFKC').toLowerCase().trim();
const translit = transliterateText(normalizedText);
return `${normalizedText} ${translit}`;
};
/**
* 类型安全的对象取值函数
*/
function getPropertyByPath<T>(
obj: T,
path: string | string[]
): string | undefined {
const keys = Array.isArray(path) ? path : path.split('.');
let value: unknown = obj;
for (const key of keys) {
if (value && typeof value === 'object' && key in value) {
value = (value as Record<string, unknown>)[key];
} else {
return undefined;
}
}
return typeof value === 'string' ? value : undefined;
}
// --- fallback 模糊匹配算法 ---
const fallbackFuzzyMatch = (text: string, pattern: string): boolean => {
@ -70,6 +92,23 @@ export function fuzzyMatch<T extends object>(
threshold,
minMatchCharLength,
ignoreLocation: true,
findAllMatches: true,
isCaseSensitive: false,
getFn: (obj, path) => {
const value = getPropertyByPath(obj, path);
if (typeof value === 'string') {
const normalized = value
.normalize('NFKC')
.replace(/\s+/g, '')
.toLowerCase()
.trim();
const translit = transliterateText(normalized);
logger.debug(`${normalized} => ${translit}`);
// 拼接原文 + 转写,提升中外文混合匹配效果
return `${normalized} ${translit}`;
}
return value;
},
sortFn: (a, b) => {
const itemA = a.item as T;
const itemB = b.item as T;
@ -83,6 +122,8 @@ export function fuzzyMatch<T extends object>(
},
});
logger.debug('Fuzzy search options:', options);
logger.debug('Fuzzy search keyword:', k);
return fuse.search(k).map((result) => result.item);
}

View File

@ -0,0 +1,17 @@
import { pinyin } from 'pinyin-pro';
/**
* 将汉语文本转换为拼音形式
*/
export function transliterateText(input: string): string {
if (!input) return '';
const text = input.normalize('NFKC').trim();
// 检测是否包含中文字符
if (/[\u4e00-\u9fa5]/.test(text)) {
return pinyin(text, { toneType: 'none', type: 'array' }).join('');
}
// 否则返回原文本
return text;
}