npm package: @skyworth/query-builder
Description: Query builder input with autocomplete extracted from react-jql
Latest version: 0.1.11

# QueryBuilder 功能完整说明文档

## 概述

QueryBuilder 是一个功能强大的 React 组件，用于构建和验证 JQL（Jira Query Language）风格的查询语句。它提供了智能建议、实时验证、上下文感知的自动完成等功能，让用户能够轻松构建复杂的查询条件。

## 核心功能

### 1. JQL 查询构建

#### 1.1 查询格式
- **标准格式**：`字段 操作符 值 关键词`
- **示例**：`runningTime = 2 And activityDuration = 2 And dataUsage > 1024`
- **支持的操作符**：
  - 比较操作符：`=`, `!=`, `>`, `<`, `>=`, `<=`
  - 字符串操作符：`LIKE`
  - 集合操作符：`IN`
- **支持的关键词**：`And`, `Or`
- **支持的括号**：`(`, `)` 用于组合复杂条件

#### 1.2 查询示例
```
runningTime = 2 And activityDuration = 2 And dataUsage > 1024 And rssi > -70 And cpuUsage > 50 And memoryUsage < 1024 And storageUsage < 1024 And iptvErrorCount < 10 And installedApp = 'com.droidlogic.tv.settings' And appRunningDuration = 30 And appOpenTimes > 10
```

### 2. 智能建议系统（Autocomplete）

#### 2.1 自动弹出机制
- **上下文感知**：根据光标位置和前面的 token 类型，智能判断应该显示什么类型的建议
- **实时更新**：输入时实时更新建议列表
- **位置计算**：根据输入框位置和光标位置，智能计算建议列表的显示位置
- **视口适配**：自动调整位置，确保建议列表在视口内可见

#### 2.2 建议类型
- **字段建议（field）**：显示可用的字段列表
  - 示例：`runningTime`, `activityDuration`, `installedApp`
- **操作符建议（operator）**：显示字段允许的操作符
  - 根据字段类型和配置，显示不同的操作符列表
- **值建议（value）**：显示字段的可选值
  - 支持字段特定的值列表（如 `installedApp` 的应用列表）
  - 支持部分值搜索和过滤
- **关键词建议（keyword）**：`And`, `Or`
- **括号建议（paren_open/paren_close）**：`(`, `)`

#### 2.3 上下文感知逻辑
- **字段后**：显示操作符建议
- **操作符后**：显示值建议
- **值后**：显示关键词建议
- **关键词后**：显示字段建议
- **IN 操作符内**：显示值建议，支持逗号分隔的多个值

### 3. 操作符插入逻辑

#### 3.1 智能位置判断
- **字段与值之间**：当光标在字段和值之间时，操作符插入到正确位置
- **替换现有操作符**：如果字段后已有操作符，会替换而不是追加
- **光标位置检测**：根据光标位置，智能判断操作符应该插入的位置

#### 3.2 IN 操作符特殊处理
- **自动添加括号**：选择第一个值时，自动在值前添加左括号 `(`
- **保持建议打开**：选择值后，建议列表保持打开，方便继续输入
- **逗号后建议**：输入逗号后，自动弹出字段的可选值建议
- **右括号关闭**：输入右括号后，自动关闭建议列表，结束 IN 操作符

**示例流程**：
1. 输入 `modelType IN`，选择值 `0`
2. 自动生成：`modelType IN (0`
3. 建议列表保持打开
4. 输入逗号：`modelType IN (0,`
5. 自动弹出 `modelType` 的可选值建议
6. 继续选择值，重复步骤 4-5
7. 输入右括号：`modelType IN (0, 1)`
8. 建议列表关闭

### 4. 值插入逻辑

#### 4.1 自动格式化
- **字符串类型**：自动添加引号，如 `'com.example.app'`
- **数字类型**：不加引号，如 `100`
- **布尔值**：`TRUE`, `FALSE`
- **NULL 值**：`NULL`

#### 4.2 部分值搜索和替换
- **实时搜索**：输入部分值（如 `installedApp = aa`）时，自动过滤建议列表
- **智能替换**：选择建议时，替换部分值而不是追加
- **支持所有字段**：不仅限于 `installedApp`，所有有可选值的字段都支持

#### 4.3 IN 操作符的值处理
- **自动添加括号**：如果 `IN` 操作符后没有括号，会自动添加
- **逗号分隔**：多个值用逗号分隔
- **自动处理空格**：逗号后自动添加空格

### 5. 查询验证系统

#### 5.1 实时验证
- **输入时验证**：输入时实时验证查询语法
- **错误提示**：显示错误位置和错误信息
- **验证图标**：显示绿色对勾（✓）或红色叉号（✗）

#### 5.2 语法验证规则
- **字段后必须跟操作符**：字段后不能直接跟值或关键词
- **操作符后必须跟值**：操作符后不能直接跟关键词
- **值后可以跟关键词或结束**：值后可以跟 `And`/`Or` 或结束查询
- **关键词后必须跟字段**：关键词后不能直接跟操作符或值
- **查询完整性**：
  - 查询不能以字段、操作符或关键词结尾（不完整）
  - 查询必须以值结尾

#### 5.3 类型验证
- **字符串字段**：不能使用数值比较操作符（`>`, `<`, `>=`, `<=`）
- **数字字段**：值必须是有效数字
- **字符串值**：应该用引号包裹（警告，不是错误）

#### 5.4 字段依赖验证
- **必需字段**：某些字段需要其他字段同时存在
  - 示例：`appRunningDuration` 需要 `installedApp` 字段
- **依赖规则配置**：通过 `validationConfig.fieldDependencies` 配置

#### 5.5 字段操作符验证
- **允许的操作符**：验证字段是否允许使用指定的操作符
- **操作符规则配置**：通过 `validationConfig.fieldOperators` 配置

#### 5.6 括号验证
- **括号匹配**：左括号和右括号必须匹配
- **字符串中的括号**：字符串中的括号不会被识别为括号 token

### 6. 解析器（Parser）

#### 6.1 Token 识别
- **字段（field）**：如 `runningTime`, `installedApp`
- **操作符（operator）**：如 `=`, `>`, `IN`
- **值（value）**：
  - 引号包裹的字符串：`'com.example.app'`
  - 数字：`100`, `-70`
  - 布尔值：`TRUE`, `FALSE`
  - NULL：`NULL`
- **关键词（keyword）**：`And`, `Or`
- **括号（paren_open, paren_close）**：`(`, `)`

#### 6.2 特殊处理
- **字符串中的括号**：字符串中的括号不会被识别为括号 token
- **空格处理**：正确处理空格分隔的 token
- **引号处理**：支持单引号和双引号
- **逗号处理**：在 `IN` 操作符中，逗号用于分隔值

### 7. 应用列表管理（App List）

#### 7.1 外部数据同步
- **实时同步**：外部 `appList` prop 更新时，自动同步到组件内部
- **智能合并**：如果用户通过 `setApps`/`appendApps` 修改过列表，外部新增数据时会智能合并
- **去重处理**：`appendApps` 会自动去重，避免重复添加

#### 7.2 数据源更新刷新
- **自动刷新建议**：当 `appList` 数据源增加时，如果建议列表正在显示，会自动刷新显示新的数据
- **实时更新**：数据变化时，组件内部状态立即更新

### 8. 应用选择器（App Selector）

#### 8.1 自定义渲染
- **灵活配置**：通过 `renderAppSelector` 自定义应用选择器的 UI
- **完整上下文**：提供完整的上下文信息，包括应用列表、搜索关键词等

#### 8.2 内置搜索功能
- **搜索关键词管理**：
  - `searchKeyword`：当前搜索关键词（组件内部管理）
  - `setSearchKeyword`：设置搜索关键词的函数
- **过滤列表**：
  - `filteredApps`：根据搜索关键词过滤后的应用列表
  - `apps`：完整的应用列表

#### 8.3 列表操作
- **设置列表**：`setApps` - 完全替换应用列表
- **追加列表**：`appendApps` - 追加应用列表（自动去重）
- **刷新列表**：`refreshApps` - 刷新列表并清空搜索关键词

#### 8.4 滚动加载支持
- **滚动事件处理**：
  - `onScroll`：滚动事件处理函数（已添加节流，200ms）
  - 只响应 app 选择器容器的滚动，不会响应建议列表的滚动
- **外部处理**：通过 `onAppListScroll` 回调，外部可以处理滚动到底部的逻辑

#### 8.5 搜索回调
- **服务器端搜索**：通过 `onSearch` 回调，支持服务器端搜索
- **防抖处理**：搜索事件使用 300ms 防抖，避免频繁调用接口

### 9. 后台搜索接口集成

#### 9.1 自动触发搜索
- **部分值检测**：当用户在输入框中输入部分值（如 `installedApp = aa`）时，自动检测
- **调用接口**：如果是 `installedApp` 字段，会调用 `onAppListSearch` 回调函数
- **防抖机制**：使用 300ms 防抖，避免频繁调用接口
- **避免重复调用**：跟踪上次搜索的关键词，只有关键词变化时才调用接口

#### 9.2 搜索范围
- **支持所有字段**：不仅限于 `installedApp`，所有字段都支持
- **排除 IN 操作符**：IN 操作符有自己的处理逻辑，不会触发后台搜索

### 10. 焦点管理

#### 10.1 智能焦点处理
- **建议列表焦点**：点击建议列表不会关闭
- **应用选择器焦点**：点击应用选择器不会关闭建议列表
- **失焦处理**：只有当焦点离开输入框、建议列表和应用选择器时，才关闭建议列表
- **延迟关闭**：使用 200ms 延迟，避免快速切换焦点时误关闭

### 11. 键盘导航

#### 11.1 快捷键支持
- **上下箭头**：在建议列表中导航
- **Enter/Tab**：选择当前选中的建议
- **Escape**：关闭建议列表
- **跳过禁用项**：导航时自动跳过禁用的建议

### 12. 光标位置管理

#### 12.1 光标跟踪
- **实时跟踪**：实时跟踪光标位置
- **智能定位**：根据光标位置确定应该显示什么类型的建议
- **位置计算**：插入建议后，光标自动定位到合适的位置

### 13. 建议列表显示

#### 13.1 位置计算
- **智能定位**：根据输入框位置和光标位置，智能计算建议列表的显示位置
- **视口适配**：自动调整位置，确保建议列表在视口内可见
- **滚动适配**：窗口滚动或调整大小时，自动更新建议列表位置

### 14. 字段标签和过滤

#### 14.1 字段标签
- **标签系统**：字段可以配置标签（如 `appMetric`）
- **字段过滤**：可以通过 `filterFields` 过滤显示的字段
- **应用指标控制**：通过 `allowAppMetrics` 控制是否显示应用相关字段

### 15. 查询预览

#### 15.1 预览功能
- **预览显示**：可以显示查询预览
- **自定义渲染**：通过 `renderPreview` 自定义预览的渲染方式
- **可配置**：通过 `showPreview` 控制是否显示预览

### 16. 自定义数据源

#### 16.1 数据源配置
- **字段数据源**：可以自定义字段列表
- **操作符数据源**：可以自定义操作符列表
- **值数据源**：可以自定义值列表
- **字段值映射**：可以为每个字段配置可选值列表
- **字段类型映射**：可以为每个字段配置类型（string/number）
- **字段操作符映射**：可以为每个字段配置允许的操作符

### 17. 验证配置

#### 17.1 配置选项
- **字段依赖规则**：配置字段之间的依赖关系
- **字段操作符规则**：配置字段允许的操作符
- **自定义验证器**：可以传入自定义的验证函数

### 18. 样式和布局

#### 18.1 样式定制
- **自定义样式**：通过 `className` 自定义容器样式
- **宽度控制**：通过 `width` 和 `maxWidth` 控制宽度
- **标题和描述**：可以显示标题和描述
- **验证图标**：可以显示验证状态图标

## 技术特性

### 1. 受控/非受控组件
- **受控模式**：通过 `value` prop 控制查询值
- **非受控模式**：通过 `defaultValue` prop 设置初始值

### 2. 性能优化
- **计算结果缓存**：使用 `useMemo` 缓存计算结果
- **函数引用缓存**：使用 `useCallback` 缓存函数引用
- **滚动事件节流**：滚动事件每 200ms 最多触发一次
- **搜索防抖**：搜索事件使用 300ms 防抖
- **建议列表位置计算优化**：使用 `requestAnimationFrame` 优化位置计算

### 3. 事件处理
- **防止事件冒泡**：正确处理事件冒泡
- **焦点事件**：正确处理焦点事件
- **键盘事件**：正确处理键盘事件
- **滚动事件**：正确处理滚动事件，区分不同来源

### 4. 状态管理
- **内部状态管理**：组件内部管理查询状态
- **外部状态同步**：支持外部状态同步
- **状态更新优化**：优化状态更新逻辑，避免不必要的重渲染

## 使用场景

### 1. 设备查询
查询设备信息，如：
```
runningTime > 100 And cpuUsage < 80 And memoryUsage < 1024
```

### 2. 应用筛选
筛选安装了特定应用的设备，如：
```
installedApp = 'com.example.app'
```

### 3. 多条件组合
使用 `And`/`Or` 组合多个条件，如：
```
(runningTime > 100 Or cpuUsage < 80) And memoryUsage < 1024
```

### 4. 范围查询
使用 `IN` 操作符查询多个值，如：
```
installedApp IN ('com.example.app1', 'com.example.app2')
modelType IN (0, 1, 2)
```

### 5. 复杂查询
使用括号组合复杂条件，如：
```
(runningTime > 100 And cpuUsage < 80) Or (memoryUsage < 1024 And storageUsage < 512)
```

## 注意事项

### 1. JQL 格式要求
- **格式规范**：必须遵循 `字段 操作符 值 关键词` 的格式
- **字符串值**：字符串值必须用引号包裹
- **数字值**：数字值不需要引号
- **操作符位置**：操作符必须插入到字段和值之间

### 2. 查询完整性
- **不能以字段结尾**：查询不能以字段、操作符或关键词结尾
- **必须以值结尾**：查询必须以值结尾

### 3. 字段依赖
- **必需字段**：某些字段需要其他字段同时存在
- **依赖检查**：组件会自动检查字段依赖关系

### 4. 滚动加载
- **滚动来源**：滚动事件只响应 app 选择器的滚动，不会响应建议列表的滚动
- **节流处理**：滚动事件使用节流处理，避免频繁触发

### 5. 搜索功能
- **防抖处理**：搜索事件使用防抖处理，避免频繁调用接口
- **IN 操作符**：IN 操作符不会触发后台搜索接口

### 6. 字符串中的括号
- **字符串处理**：字符串中的括号不会被识别为括号 token
- **引号包裹**：字符串值必须用引号包裹

## API 参考

### Props

#### 基础 Props
- `value?: string` - 受控模式的查询值
- `defaultValue?: string` - 非受控模式的初始值
- `onChange?: (value: string) => void` - 查询值变化回调

#### 数据源 Props
- `data?: Partial<QueryBuilderDataSources>` - 自定义数据源
- `appList?: AppOption[]` - 应用列表
- `onAppListScroll?: (event: React.UIEvent<HTMLElement>) => void` - 应用列表滚动回调
- `onAppListSearch?: (keyword: string) => void` - 应用列表搜索回调

#### 验证 Props
- `validate?: (query: string) => ValidationError[]` - 自定义验证函数
- `validationConfig?: ValidationConfig` - 验证配置
- `enforceFieldDependencies?: boolean` - 是否强制执行字段依赖
- `enforceFieldOperators?: boolean` - 是否强制执行字段操作符限制

#### UI Props
- `placeholder?: string` - 输入框占位符
- `title?: string` - 标题
- `description?: string` - 描述
- `className?: string` - 自定义样式类名
- `showPreview?: boolean` - 是否显示预览
- `renderPreview?: (query: string) => ReactNode` - 自定义预览渲染
- `previewLabel?: string` - 预览标签
- `width?: string` - 宽度
- `maxWidth?: string` - 最大宽度
- `showHeader?: boolean` - 是否显示头部
- `showValidationIcon?: boolean` - 是否显示验证图标

#### 功能 Props
- `allowAppMetrics?: boolean` - 是否允许应用指标字段
- `filterFields?: (field: Suggestion) => boolean` - 字段过滤函数
- `renderAppSelector?: (context: AppSelectorContext) => ReactNode` - 自定义应用选择器渲染

### AppSelectorContext

应用选择器上下文对象，包含以下属性：

- `apps: AppOption[]` - 完整的应用列表
- `filteredApps: AppOption[]` - 过滤后的应用列表
- `searchKeyword: string` - 当前搜索关键词
- `setSearchKeyword: (keyword: string) => void` - 设置搜索关键词
- `setApps: (apps: AppOption[]) => void` - 设置应用列表
- `appendApps: (apps: AppOption[]) => void` - 追加应用列表
- `refreshApps: () => void` - 刷新应用列表
- `onScroll?: (event: React.UIEvent<HTMLElement>) => void` - 滚动事件处理
- `onSearch?: (keyword: string) => void` - 搜索事件回调

## 更新日志

### 最新功能
- ✅ 支持后台搜索接口集成（`onAppListSearch`）
- ✅ 优化 IN 操作符逻辑（选择值后保持打开，逗号后弹出建议，右括号关闭）
- ✅ 支持部分值搜索和替换
- ✅ 数据源更新时自动刷新建议列表
- ✅ 优化逗号后输入空格时的建议显示

### 已知问题
- 无

## 贡献指南

欢迎提交 Issue 和 Pull Request 来改进这个组件。

## 许可证

MIT License