/** * FeatureFilter - PFP特征筛选类 * 支持从API加载特征数据,并根据选中的特征进行筛选 * 支持AND/OR逻辑 */ class FeatureFilter { constructor() { this.cache = new BrowserCache(); this.categoryData = null; this.selectedFeatures = new Map(); // 存储选中的特征 Map this.logicMode = 'OR'; // 'AND' 或 'OR',默认OR(满足任一特征) this.apiUrl = 'https://h5.shuziwenbo.cn/json/shpfp/category.json'; } /** * 从API加载特征分类数据(带缓存) * @returns {Promise} 特征数据 */ async loadCategoryData() { // 1. 检查缓存 const cached = this.cache.getCache('category_data'); if (cached) { this.categoryData = cached; console.log('✓ 使用缓存的特征数据'); return cached; } // 2. 从API获取 try { console.log('→ 从API加载特征数据...'); const response = await fetch(this.apiUrl); if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } const result = await response.json(); // 3. 缓存数据(24小时) this.cache.setCache('category_data', result); this.categoryData = result; console.log(`✓ 特征数据加载完成,共 ${result.data.length} 个分类`); return result; } catch (error) { console.error('✗ 加载特征数据失败:', error); throw error; } } /** * 获取已加载的特征数据 * @returns {Object|null} */ getCategoryData() { return this.categoryData; } /** * 选中一个特征 * @param {string} category - 特征分类 * @param {string} feature - 特征名称 * @param {Array} items - 包含该特征的PFP编号数组 */ selectFeature(category, feature, items) { const featureKey = `${category}_${feature}`; this.selectedFeatures.set(featureKey, { category, feature, items }); } /** * 取消选中一个特征 * @param {string} featureKey - 特征键 */ deselectFeature(featureKey) { this.selectedFeatures.delete(featureKey); } /** * 清除所有选中的特征 */ clearAllSelections() { this.selectedFeatures.clear(); } /** * 获取所有选中的特征 * @returns {Map} */ getSelectedFeatures() { return this.selectedFeatures; } /** * 设置逻辑模式 * @param {string} mode - 'AND' 或 'OR' */ setLogicMode(mode) { this.logicMode = mode; } /** * 获取当前逻辑模式 * @returns {string} */ getLogicMode() { return this.logicMode; } /** * 检查筛选是否激活 * @returns {boolean} */ isActive() { return this.selectedFeatures.size > 0; } /** * 根据选中的特征筛选PFP数据 * @param {Array} dataArray - PFP数据数组 * @param {Map} selectedFeatures - 选中的特征Map * @param {string} logicMode - 逻辑模式 ('AND' 或 'OR') * @returns {Array} 筛选后的数据数组 */ filterByFeatures(dataArray, selectedFeatures, logicMode) { if (selectedFeatures.size === 0) { return dataArray; } const featuresArray = Array.from(selectedFeatures.values()); if (logicMode === 'AND') { // AND逻辑:PFP必须同时满足所有选中的特征 return dataArray.filter(pfp => { return featuresArray.every(feature => { // 将items数组中的字符串转换为数字进行比较 const itemNums = feature.items.map(item => parseInt(item)); return itemNums.includes(pfp.num); }); }); } else { // OR逻辑:PFP满足任一选中的特征即可 // 使用Set优化查找性能 const matchingNums = new Set(); featuresArray.forEach(feature => { feature.items.forEach(item => { matchingNums.add(parseInt(item)); }); }); return dataArray.filter(pfp => matchingNums.has(pfp.num)); } } }