6.4 KiB
6.4 KiB
搜索场景下本地数据处理方案
场景分析
场景一:新增数据后的搜索
问题:用户新增了10条数据(仅在本地,未保存到数据库),执行 LIKE 搜索时,这些本地数据无法被搜索到。
期望:搜索结果应包含本地新增的行,且支持 LIKE 模糊匹配。
场景二:更新数据后的搜索
问题:用户更新了10条数据(本地已修改),执行搜索时,远程返回的是旧数据,本地修改的数据可能不符合搜索条件。
期望:搜索结果应使用本地更新后的数据进行匹配,而不是远程的旧数据。
解决方案
方案核心思路
- 本地数据也参与搜索过滤:在搜索时,对本地的
insertRows和updateRows也应用搜索条件过滤 - 合并展示:将远程搜索结果与本地过滤后的结果合并展示
- 保持状态:保留本地数据的
_rowState标记
修改内容
1. JS 文件修改 (js/feegrid-manager.js)
新增方法:
-
_filterLocalRows(condition)- 根据搜索条件过滤本地数据 -
修改
loadPage()- 在加载远程数据后,合并本地过滤后的数据
搜索条件解析:
-
支持
LIKE '%xxx%'模糊匹配 -
支持
=,!=,<,>,<=,>=比较 -
支持
AND,OR逻辑(简化版)
2. 修改 loadPage() 方法
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. 新增条件解析工具函数
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;
}
实施步骤
-
修改
js/feegrid-manager.js:-
新增
_filterLocalRows()函数 -
新增
_parseCondition()函数 -
新增
_matchesConditions()函数 -
修改
loadPage()方法,在加载时过滤本地数据
-
-
修改
reload()方法:- 确保
reload()时也应用本地数据过滤
- 确保
-
测试验证:
-
测试新增数据后的 LIKE 搜索
-
测试更新数据后的搜索匹配
-
预期效果
| 场景 | 操作 | 预期结果 |
|---|---|---|
| 场景一 | 新增10条数据 → 搜索 LIKE '%xxx%' | 本地新增且匹配的行会显示在搜索结果中 |
| 场景二 | 更新10条数据 → 搜索更新后的字段 | 使用本地更新后的数据进行匹配 |
| 场景三 | 删除数据后搜索 | 已标记删除的行仍然出现在搜索结果中,但是status显示删除即可 |
风险与注意事项
- 条件解析复杂度:只支持简单的 LIKE、=、!= 操作符,复杂条件可能解析失败
- 性能考虑:本地数据量大时,过滤可能有性能问题(建议限制本地数据量)
- 日期格式:日期字段的比较需要注意格式统一
- 多表关联:不支持跨表字段的搜索条件