# GlobalSearch - 全局搜索模块 ## 模块概述 `GlobalSearch` 是 OneApp 的全局搜索模块,提供了跨模块的统一搜索功能。该模块支持多种内容类型的搜索,包括智能搜索建议、搜索历史管理、搜索结果优化等功能,为用户提供高效、精准的搜索体验。 ## 核心功能 ### 1. 跨模块内容搜索 - **统一搜索入口**:提供全局统一的搜索接口 - **多模块索引**:聚合各模块的可搜索内容 - **内容分类**:按类型分类搜索结果 - **权限控制**:基于用户权限过滤搜索结果 ### 2. 智能搜索建议 - **实时建议**:输入时实时提供搜索建议 - **热门搜索**:展示热门搜索关键词 - **个性化推荐**:基于用户行为的个性化建议 - **拼写纠错**:智能纠正搜索词拼写错误 ### 3. 搜索历史管理 - **历史记录**:保存用户搜索历史 - **快速访问**:快速访问历史搜索结果 - **清理管理**:支持清理搜索历史 - **隐私保护**:敏感搜索历史加密存储 ### 4. 搜索结果优化 - **相关性排序**:按相关性智能排序 - **结果聚合**:相似结果智能聚合 - **高亮显示**:关键词高亮显示 - **分页加载**:大量结果分页展示 ## 技术架构 ### 架构设计 ``` ┌─────────────────────────────────────┐ │ 搜索界面层 │ │ (Search UI Components) │ ├─────────────────────────────────────┤ │ GlobalSearch 模块 │ │ ┌──────────┬──────────┬──────────┐ │ │ │ 搜索引擎 │ 索引管理 │ 结果处理 │ │ │ ├──────────┼──────────┼──────────┤ │ │ │ 建议系统 │ 历史管理 │ 缓存层 │ │ │ └──────────┴──────────┴──────────┘ │ ├─────────────────────────────────────┤ │ 模块搜索接口 │ │ ┌──────────┬──────────┬──────────┐ │ │ │ 车辆模块 │ 订单模块 │ 设置模块 │ │ │ └──────────┴──────────┴──────────┘ │ ├─────────────────────────────────────┤ │ 数据存储层 │ │ (Local DB + Remote Index) │ └─────────────────────────────────────┘ ``` ### 核心组件 #### 1. 通用搜索组件 (GlobalSearchCommonWidget) 基于真实项目代码的通用搜索组件: ```dart /// 全局搜索通用组件 class GlobalSearchCommonWidget extends StatefulWidget { const GlobalSearchCommonWidget({ Key? key, required this.selectCommonSearchItem }) : super(key: key); final SelectCommonSearch selectCommonSearchItem; @override State createState() => _GlobalSearchCommonWidgetState(); } /// 搜索项目数据模型 class SearchItemBean { String name; String event; SearchItemBean({required this.name, required this.event}); } /// 选择通用搜索项回调 typedef SelectCommonSearch = void Function(SearchItemBean commonSearchItem); ``` #### 2. 搜索组件实现 ```dart class _GlobalSearchCommonWidgetState extends State { List commonSearchBeanList = []; String tips = ''; @override Widget build(BuildContext context) { if (commonSearchBeanList.isEmpty) { return Container(); } return Column( mainAxisSize: MainAxisSize.min, children: [ Container( padding: EdgeInsets.fromLTRB(15, 15, 12, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( tips, style: OneTextStyle.content(color: OneColors.tc), ), ], ), SizedBox(height: 10), Wrap( spacing: 8, runSpacing: 12, children: _buildHistoryTag(commonSearchBeanList), ), ], ), ), ], ); } /// 构建历史搜索标签 List _buildHistoryTag(List historys) { List historyWidgets = []; for (int i = 0; i < historys.length; i++) { var displayName = historys[i].name; if (displayName.length > 8) { displayName = displayName.substring(0, 8) + '...'; } historyWidgets.add(InkWell( onTap: () { widget.selectCommonSearchItem(historys[i]); }, child: Container( padding: EdgeInsets.fromLTRB(5, 0, 5, 0), decoration: BoxDecoration( color: OneColors.bgcSub1, borderRadius: BorderRadius.all(Radius.circular(2)), ), child: Text( displayName, style: OneTextStyle.content( color: OneColors.tc.withOpacity(0.55), ), ), ), )); } return historyWidgets; } @override void initState() { super.initState(); getCommonSearchResult(); } /// 获取通用搜索结果 void getCommonSearchResult() { // 实际项目中的搜索数据获取逻辑 } } ``` #### 3. 搜索组件架构 实际项目包含的搜索组件: - **QuicklyAccess.dart**: 快速访问组件 - **search_all_result_widget.dart**: 全部搜索结果组件 - **search_common_widget.dart**: 通用搜索组件 - **search_event_result_widget.dart**: 事件搜索结果组件 - **search_history_widget.dart**: 搜索历史组件 - **search_input_TextField_widget.dart**: 搜索输入框组件 - **search_mall_result_widget.dart**: 商城搜索结果组件 - **search_post_result_widget.dart**: 帖子搜索结果组件 - **search_result_widget.dart**: 搜索结果组件 ## 数据模型 ### 搜索查询模型 ```dart class SearchQuery { final String keyword; final List categories; final SearchScope scope; final SortOption sortBy; final int page; final int pageSize; final Map filters; final bool includeHistory; } enum SearchScope { all, // 全部内容 vehicle, // 车辆相关 order, // 订单相关 service, // 服务相关 settings, // 设置相关 help // 帮助文档 } enum SortOption { relevance, // 相关性 time, // 时间 popularity, // 热度 alphabetical // 字母顺序 } ``` ### 搜索结果模型 ```dart class SearchResult { final String query; final int totalCount; final List items; final List suggestions; final Duration searchTime; final Map categoryCount; final bool hasMore; } class SearchResultItem { final String id; final String title; final String? subtitle; final String? description; final String category; final String moduleId; final String? imageUrl; final double relevanceScore; final DateTime? timestamp; final Map metadata; final List highlights; } ``` ### 搜索建议模型 ```dart class SearchSuggestion { final String text; final SuggestionType type; final String? category; final int frequency; final double relevance; final Map? metadata; } enum SuggestionType { keyword, // 关键词建议 history, // 历史搜索 popular, // 热门搜索 completion, // 自动补全 correction // 拼写纠错 } ``` ## API 接口 ### 搜索接口 ```dart abstract class GlobalSearchService { // 执行全局搜索 Future> search(SearchRequest request); // 获取搜索建议 Future>> getSuggestions(SuggestionRequest request); // 获取热门搜索 Future>> getPopularSearches(); // 获取搜索历史 Future>> getSearchHistory(HistoryRequest request); } ``` ### 索引管理接口 ```dart abstract class SearchIndexService { // 更新搜索索引 Future> updateSearchIndex(UpdateIndexRequest request); // 删除搜索索引 Future> deleteSearchIndex(DeleteIndexRequest request); // 获取索引状态 Future> getIndexStatus(String moduleId); } ``` ### 搜索提供者接口 ```dart abstract class SearchProvider { // 搜索提供者ID String get providerId; // 支持的搜索类别 List get supportedCategories; // 执行搜索 Future> search(SearchQuery query); // 获取可搜索项目 Future> getSearchableItems(); // 获取搜索建议 Future> getSuggestions(String input); } ``` ## 配置管理 ### 搜索配置 ```dart class GlobalSearchConfig { final int maxResults; final int suggestionLimit; final bool enableHistory; final bool enableSuggestions; final Duration cacheExpiry; final List enabledModules; final Map categoryWeights; static const GlobalSearchConfig defaultConfig = GlobalSearchConfig( maxResults: 100, suggestionLimit: 10, enableHistory: true, enableSuggestions: true, cacheExpiry: Duration(minutes: 30), enabledModules: ['vehicle', 'order', 'service', 'settings'], categoryWeights: { 'vehicle': 1.0, 'order': 0.8, 'service': 0.9, 'settings': 0.6, }, ); } ``` ### 索引配置 ```dart class SearchIndexConfig { final bool enableRealTimeIndex; final Duration indexUpdateInterval; final int maxIndexSize; final List indexedFields; final Map fieldWeights; static const SearchIndexConfig defaultIndexConfig = SearchIndexConfig( enableRealTimeIndex: true, indexUpdateInterval: Duration(minutes: 5), maxIndexSize: 10000, indexedFields: ['title', 'description', 'tags', 'content'], fieldWeights: { 'title': 3, 'description': 2, 'tags': 2, 'content': 1, }, ); } ``` ## 使用示例 ### 基本搜索功能 ```dart // 初始化全局搜索 final globalSearch = GlobalSearchEngine.instance; await globalSearch.initialize(GlobalSearchConfig.defaultConfig); // 执行搜索 final searchQuery = SearchQuery( keyword: '充电', categories: ['vehicle', 'service'], scope: SearchScope.all, sortBy: SortOption.relevance, page: 1, pageSize: 20, ); final searchResult = await globalSearch.search(searchQuery); // 处理搜索结果 for (final item in searchResult.items) { print('${item.title}: ${item.description}'); print('类别: ${item.category}, 相关性: ${item.relevanceScore}'); } ``` ### 搜索建议功能 ```dart // 获取输入建议 final suggestions = await globalSearch.getSuggestions('充电'); // 显示建议列表 for (final suggestion in suggestions) { switch (suggestion.type) { case SuggestionType.completion: print('补全: ${suggestion.text}'); break; case SuggestionType.history: print('历史: ${suggestion.text}'); break; case SuggestionType.popular: print('热门: ${suggestion.text}'); break; } } // 获取热门搜索 final popularSearches = await globalSearch.getPopularSearches(); print('热门搜索: ${popularSearches.join(', ')}'); ``` ### 搜索历史管理 ```dart // 添加搜索记录 final searchRecord = SearchRecord( query: '充电站', timestamp: DateTime.now(), resultCount: 25, category: 'vehicle', ); await SearchHistoryManager.instance.addSearchRecord(searchRecord); // 获取搜索历史 final history = await SearchHistoryManager.instance.getSearchHistory(limit: 10); for (final record in history) { print('${record.query} - ${record.timestamp}'); } // 清空搜索历史 await SearchHistoryManager.instance.clearSearchHistory(); ``` ### 注册搜索提供者 ```dart // 实现搜索提供者 class VehicleSearchProvider extends SearchProvider { @override String get providerId => 'vehicle_search'; @override List get supportedCategories => ['vehicle', 'charging', 'maintenance']; @override Future> search(SearchQuery query) async { // 实现车辆相关内容搜索 final vehicles = await vehicleService.searchVehicles(query.keyword); return vehicles.map((vehicle) => SearchResultItem( id: vehicle.id, title: vehicle.name, description: vehicle.description, category: 'vehicle', moduleId: 'app_car', relevanceScore: calculateRelevance(query.keyword, vehicle), )).toList(); } @override Future> getSuggestions(String input) async { // 返回车辆相关搜索建议 return vehicleService.getSearchSuggestions(input); } } // 注册搜索提供者 globalSearch.registerSearchProvider(VehicleSearchProvider()); ``` ## 测试策略 ### 单元测试 ```dart group('GlobalSearch Tests', () { test('should return search results', () async { // Given final searchEngine = GlobalSearchEngine(); final query = SearchQuery(keyword: 'test', scope: SearchScope.all); // When final result = await searchEngine.search(query); // Then expect(result.items, isNotEmpty); expect(result.query, 'test'); }); test('should provide search suggestions', () async { // Given final suggestionSystem = SearchSuggestionSystem(); // When final suggestions = await suggestionSystem.generateSuggestions('cha'); // Then expect(suggestions, isNotEmpty); expect(suggestions.first.text, contains('cha')); }); }); ``` ### 集成测试 ```dart group('Search Integration Tests', () { testWidgets('complete search flow', (tester) async { // 1. 输入搜索关键词 await tester.enterText(find.byKey(Key('search_input')), '充电'); // 2. 验证搜索建议显示 expect(find.text('充电站'), findsOneWidget); expect(find.text('充电桩'), findsOneWidget); // 3. 执行搜索 await tester.tap(find.byKey(Key('search_button'))); await tester.pumpAndSettle(); // 4. 验证搜索结果 expect(find.byType(SearchResultItem), findsWidgets); }); }); ``` ## 性能优化 ### 搜索性能优化 - **索引优化**:使用倒排索引提高搜索速度 - **缓存策略**:热门搜索结果缓存 - **分页加载**:大结果集分页加载 - **异步处理**:搜索操作异步处理 ### 内存优化 - **结果限制**:限制搜索结果数量 - **懒加载**:搜索结果懒加载 - **对象池**:复用搜索对象 - **内存回收**:及时回收不用的搜索数据 ## 算法和策略 ### 相关性算法 ```dart class RelevanceCalculator { // 计算文本相关性 double calculateTextRelevance(String query, String text); // 计算标题权重 double calculateTitleWeight(String query, String title); // 计算类别权重 double calculateCategoryWeight(String category); // 计算综合得分 double calculateFinalScore(Map scores); } ``` ### 搜索优化策略 - **查询扩展**:同义词和相关词扩展 - **模糊匹配**:支持模糊匹配搜索 - **权重调整**:动态调整搜索权重 - **个性化排序**:基于用户行为的个性化排序 ## 版本历史 ### v0.3.2+5 (当前版本) - 新增语义搜索功能 - 优化搜索性能和准确性 - 支持多语言搜索 - 修复搜索结果排序问题 ### v0.3.1 - 支持实时搜索建议 - 新增搜索历史管理 - 优化搜索索引结构 - 改进搜索结果展示 ## 依赖关系 ### 内部依赖 - `basic_storage`: 本地数据存储 - `basic_network`: 网络请求服务 - `basic_utils`: 工具类库 - `basic_logger`: 日志记录 ### 外部依赖 - `sqflite`: 本地数据库 - `fuzzywuzzy`: 模糊匹配算法 - `rxdart`: 响应式编程 - `collection`: 集合工具 ## 总结 `GlobalSearch` 模块为 OneApp 提供了强大的全局搜索能力,通过统一的搜索接口、智能的搜索建议、完善的历史管理和优化的搜索结果,为用户提供了高效、精准的搜索体验。该模块的设计充分考虑了可扩展性、性能优化和用户体验,能够很好地支撑应用的搜索需求。