- stockSlice: 新增 loadAllStocks action(带缓存检查)
- stockSlice: watchlist 结构升级为 { stock_code, stock_name }[]
- store/hooks.ts: 新增 useAppDispatch, useAppSelector 类型化 hooks
- stockService: 移除 getAllStocks(已迁移到 Redux)
- mock: 股票搜索支持模糊匹配 + 相关性排序
61 lines
2.2 KiB
JavaScript
61 lines
2.2 KiB
JavaScript
// src/services/stockService.js
|
||
// 股票数据服务 - 模糊搜索工具函数
|
||
// 注意: getAllStocks 已迁移到 Redux (stockSlice.loadAllStocks)
|
||
|
||
/**
|
||
* 股票数据服务
|
||
*/
|
||
export const stockService = {
|
||
/**
|
||
* 模糊搜索股票(匹配 code 或 name)
|
||
* @param {string} query - 搜索关键词
|
||
* @param {Array<{code: string, name: string}>} stockList - 股票列表
|
||
* @param {number} limit - 返回结果数量限制
|
||
* @returns {Array<{code: string, name: string}>}
|
||
*/
|
||
fuzzySearch(query, stockList, limit = 10) {
|
||
if (!query || !stockList || stockList.length === 0) {
|
||
return [];
|
||
}
|
||
|
||
const lowerQuery = query.toLowerCase();
|
||
|
||
// 模糊匹配 code 或 name
|
||
const results = stockList.filter(stock => {
|
||
const code = (stock.code || '').toString().toLowerCase();
|
||
const name = (stock.name || '').toLowerCase();
|
||
return code.includes(lowerQuery) || name.includes(lowerQuery);
|
||
});
|
||
|
||
// 优先级排序:
|
||
// 1. code 精确匹配
|
||
// 2. name 精确匹配
|
||
// 3. code 开头匹配
|
||
// 4. name 开头匹配
|
||
// 5. 其他包含匹配
|
||
results.sort((a, b) => {
|
||
const aCode = (a.code || '').toString().toLowerCase();
|
||
const aName = (a.name || '').toLowerCase();
|
||
const bCode = (b.code || '').toString().toLowerCase();
|
||
const bName = (b.name || '').toLowerCase();
|
||
|
||
// 精确匹配
|
||
if (aCode === lowerQuery) return -1;
|
||
if (bCode === lowerQuery) return 1;
|
||
if (aName === lowerQuery) return -1;
|
||
if (bName === lowerQuery) return 1;
|
||
|
||
// 开头匹配
|
||
if (aCode.startsWith(lowerQuery) && !bCode.startsWith(lowerQuery)) return -1;
|
||
if (!aCode.startsWith(lowerQuery) && bCode.startsWith(lowerQuery)) return 1;
|
||
if (aName.startsWith(lowerQuery) && !bName.startsWith(lowerQuery)) return -1;
|
||
if (!aName.startsWith(lowerQuery) && bName.startsWith(lowerQuery)) return 1;
|
||
|
||
// 字母顺序
|
||
return aCode.localeCompare(bCode);
|
||
});
|
||
|
||
return results.slice(0, limit);
|
||
}
|
||
};
|