# 搜索场景下本地数据处理方案 ## 场景分析 ### 场景一:新增数据后的搜索 **问题**:用户新增了10条数据(仅在本地,未保存到数据库),执行 LIKE 搜索时,这些本地数据无法被搜索到。 **期望**:搜索结果应包含本地新增的行,且支持 LIKE 模糊匹配。 ### 场景二:更新数据后的搜索 **问题**:用户更新了10条数据(本地已修改),执行搜索时,远程返回的是旧数据,本地修改的数据可能不符合搜索条件。 **期望**:搜索结果应使用本地更新后的数据进行匹配,而不是远程的旧数据。 *** ## 解决方案 ### 方案核心思路 1. **本地数据也参与搜索过滤**:在搜索时,对本地的 `insertRows` 和 `updateRows` 也应用搜索条件过滤 2. **合并展示**:将远程搜索结果与本地过滤后的结果合并展示 3. **保持状态**:保留本地数据的 `_rowState` 标记 ### 修改内容 #### 1. JS 文件修改 (`js/feegrid-manager.js`) **新增方法:** * `_filterLocalRows(condition)` - 根据搜索条件过滤本地数据 * 修改 `loadPage()` - 在加载远程数据后,合并本地过滤后的数据 **搜索条件解析**: * 支持 `LIKE '%xxx%'` 模糊匹配 * 支持 `=`, `!=`, `<`, `>`, `<=`, `>=` 比较 * 支持 `AND`, `OR` 逻辑(简化版) #### 2. 修改 `loadPage()` 方法 ```js function loadPage(pageNumber) { _setLoading(); var pagination = state.draftManager.getPagination(); var pageSize = pagination.pageSize; var remoteTotal = pagination.remoteTotal; var insertRows = state.draftManager.getInsertRows(); var updateRows = state.draftManager.getUpdateRows(); // 获取搜索条件 var searchCondition = options.searchCondition || options.keyField.replace('subid', 'mx_') + "='" + state.masterId + "'"; // 过滤本地数据 var filteredInserts = _filterLocalRows(insertRows, searchCondition); var filteredUpdates = _filterLocalRows(updateRows, searchCondition); // ... 原有远程加载逻辑 ... // 合并结果时,使用本地过滤后的数据 } ``` #### 3. 新增条件解析工具函数 ```js function _filterLocalRows(rows, condition) { if (!condition || condition.trim() === '') { return rows; } var filtered = []; var conditions = _parseCondition(condition); for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (_matchesConditions(row, conditions)) { filtered.push(row); } } return filtered; } function _parseCondition(condition) { var result = []; var parts = condition.split(/\s+(AND|OR)\s+/i); for (var i = 0; i < parts.length; i += 2) { var expr = parts[i].trim(); var operator = parts[i + 1] ? parts[i + 1].toUpperCase() : 'AND'; var match; // LIKE 匹配 if ((match = expr.match(/^\s*(\w+)\s+LIKE\s+['"](.*)['"]\s*$/i))) { result.push({ field: match[1], operator: 'LIKE', value: match[2], logic: operator }); } // 等于匹配 else if ((match = expr.match(/^\s*(\w+)\s*=\s*['"](.*)['"]\s*$/))) { result.push({ field: match[1], operator: '=', value: match[2], logic: operator }); } // 不等于匹配 else if ((match = expr.match(/^\s*(\w+)\s*(!=|<>)=\s*['"](.*)['"]\s*$/))) { result.push({ field: match[1], operator: '!=', value: match[2], logic: operator }); } } return result; } function _matchesConditions(row, conditions) { if (conditions.length === 0) return true; var result = true; for (var i = 0; i < conditions.length; i++) { var cond = conditions[i]; var fieldValue = row[cond.field]; if (fieldValue === undefined || fieldValue === null) { fieldValue = ''; } var fieldStr = String(fieldValue).toLowerCase(); var valueStr = String(cond.value).toLowerCase(); var matches = false; switch (cond.operator) { case 'LIKE': var pattern = valueStr .replace(/%/g, '.*') .replace(/_/g, '.'); matches = new RegExp('^' + pattern + '$').test(fieldStr); break; case '=': matches = fieldStr === valueStr; break; case '!=': matches = fieldStr !== valueStr; break; } if (cond.logic === 'AND') { result = result && matches; } else { result = result || matches; } if (!result && cond.logic === 'AND') { break; } } return result; } ``` *** ## 实施步骤 1. **修改** **`js/feegrid-manager.js`**: * 新增 `_filterLocalRows()` 函数 * 新增 `_parseCondition()` 函数 * 新增 `_matchesConditions()` 函数 * 修改 `loadPage()` 方法,在加载时过滤本地数据 2. **修改** **`reload()`** **方法**: * 确保 `reload()` 时也应用本地数据过滤 3. **测试验证**: * 测试新增数据后的 LIKE 搜索 * 测试更新数据后的搜索匹配 *** ## 预期效果 | 场景 | 操作 | 预期结果 | | --- | ------------------------- | -------------------------------- | | 场景一 | 新增10条数据 → 搜索 LIKE '%xxx%' | 本地新增且匹配的行会显示在搜索结果中 | | 场景二 | 更新10条数据 → 搜索更新后的字段 | 使用本地更新后的数据进行匹配 | | 场景三 | 删除数据后搜索 | 已标记删除的行仍然出现在搜索结果中,但是status显示删除即可 | *** ## 风险与注意事项 1. **条件解析复杂度**:只支持简单的 LIKE、=、!= 操作符,复杂条件可能解析失败 2. **性能考虑**:本地数据量大时,过滤可能有性能问题(建议限制本地数据量) 3. **日期格式**:日期字段的比较需要注意格式统一 4. **多表关联**:不支持跨表字段的搜索条件