@kc-one/smart-fill-sdk 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +542 -223
- package/dist/index.esm.js +198 -190
- package/dist/index.umd.cjs +8 -8
- package/dist/src/config/defaults.d.ts +1 -6
- package/dist/src/config/defaults.d.ts.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,223 +1,542 @@
|
|
|
1
|
-
# Smart Fill SDK
|
|
2
|
-
|
|
3
|
-
页面内智能录入 SDK,用于在业务页面嵌入「文本 / 图片识别 → 自动表单回填 → 结果反馈」能力。
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
→
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
| `
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
#### `
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
1
|
+
# Smart Fill SDK
|
|
2
|
+
|
|
3
|
+
页面内智能录入 SDK,用于在业务页面嵌入「文本 / 图片识别 → 自动表单回填 → 结果反馈」能力。
|
|
4
|
+
|
|
5
|
+
- **包名**:`@kc-one/smart-fill-sdk`
|
|
6
|
+
- **当前版本**:`0.0.12`
|
|
7
|
+
- **浏览器**:Chrome ≥ 90、Edge ≥ 90、Firefox ≥ 88、Safari ≥ 14
|
|
8
|
+
|
|
9
|
+
## 安装
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @kc-one/smart-fill-sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 快速开始
|
|
16
|
+
|
|
17
|
+
### 本地开发
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install
|
|
21
|
+
npm run dev
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
打开 Vite 示例页(`examples/vanilla/index.html`),点击「智能录入」入口。
|
|
25
|
+
|
|
26
|
+
### 业务接入
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { SmartFill } from '@kc-one/smart-fill-sdk'
|
|
30
|
+
import '@kc-one/smart-fill-sdk/style.css'
|
|
31
|
+
|
|
32
|
+
await SmartFill.setup({ apiKey: 'seKey-xxxxxxxxxxxxx' })
|
|
33
|
+
// 网关根地址见 DEFAULT_BASE_URL(src/config/defaults.ts)
|
|
34
|
+
|
|
35
|
+
const smartFill = SmartFill.create({
|
|
36
|
+
formCode: 'apply-form',
|
|
37
|
+
routeContainerSelector: '.page-container'
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
smartFill.registerFields([
|
|
41
|
+
{
|
|
42
|
+
fieldId: 'customerName',
|
|
43
|
+
label: '客户姓名',
|
|
44
|
+
type: 'text',
|
|
45
|
+
element: '[data-smart-fill-key="customerName"]'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
fieldId: 'legalBankMobile',
|
|
49
|
+
label: '法人手机号',
|
|
50
|
+
type: 'text',
|
|
51
|
+
localRuleMode: 'off', // 该字段不走本地规则,仅走后端识别
|
|
52
|
+
element: '[data-smart-fill-key="legalBankMobile"]'
|
|
53
|
+
}
|
|
54
|
+
])
|
|
55
|
+
|
|
56
|
+
smartFill.mountFloatingButton()
|
|
57
|
+
// 或嵌入指定容器:smartFill.mount('#smart-fill-entry')
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 核心流程
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
SmartFill.setup({ apiKey })
|
|
64
|
+
→ 校验 apiKey / 创建会话 / 获取 accessToken
|
|
65
|
+
SmartFill.create({ formCode, ... })
|
|
66
|
+
→ 创建页面实例,绑定网关客户端
|
|
67
|
+
smartFill.registerFields([...]) // 可选:L3 高精度字段注册
|
|
68
|
+
smartFill.mountFloatingButton() // 或 mount() 嵌入容器
|
|
69
|
+
smartFill.open() // 打开面板并 rescan
|
|
70
|
+
用户输入文本 / 上传图片,点击「智能识别」
|
|
71
|
+
→ rescan() 扫描字段,生成 scanToken
|
|
72
|
+
→ 本地规则预识别(可开关)
|
|
73
|
+
→ 后端识别网关补全
|
|
74
|
+
→ 合并结果,自动回填高置信字段(或 apiCallback 回调)
|
|
75
|
+
→ 返回 applied / skipped / warnings / traceId
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 对外 API 总览
|
|
81
|
+
|
|
82
|
+
### 类与常量
|
|
83
|
+
|
|
84
|
+
| 导出 | 说明 |
|
|
85
|
+
| --- | --- |
|
|
86
|
+
| `SmartFill` | 全局入口:`setup` / `create` / `on` |
|
|
87
|
+
| `SmartFillInstance` | 页面实例类(通常通过 `SmartFill.create()` 获取) |
|
|
88
|
+
| `DomScanner` | DOM 字段扫描器 |
|
|
89
|
+
| `DomFiller` | 表单回填执行器 |
|
|
90
|
+
| `LocalRuleEngine` | 浏览器端本地规则识别引擎 |
|
|
91
|
+
| `EventBus` | 轻量事件总线 |
|
|
92
|
+
| `NativeAdapter` | 原生 input / textarea / select 适配器 |
|
|
93
|
+
| `UiFrameworkAdapter` | Element / Ant Design Vue / Naive UI / Arco / Vant 等 UI 框架适配器 |
|
|
94
|
+
| `ElementAdapter` | `UiFrameworkAdapter` 的兼容别名 |
|
|
95
|
+
| `DEFAULT_BASE_URL` | 网关根地址常量 |
|
|
96
|
+
| `SmartFillException` | 结构化异常类 |
|
|
97
|
+
| `createError` | 创建标准 SDK 异常 |
|
|
98
|
+
| `toSmartFillError` | 将未知 error 归一化为 `SmartFillError` |
|
|
99
|
+
| `createTraceId` | 生成唯一追踪 ID |
|
|
100
|
+
|
|
101
|
+
### 类型
|
|
102
|
+
|
|
103
|
+
| 类型 | 说明 |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| `SmartFillSetupConfig` | `setup()` 配置 |
|
|
106
|
+
| `SmartFillCreateConfig` | `create()` 配置 |
|
|
107
|
+
| `FieldSchema` | 业务注册字段 Schema |
|
|
108
|
+
| `FieldDescriptor` | 扫描后的运行时字段描述 |
|
|
109
|
+
| `FieldType` / `FieldOption` | 字段类型与选项 |
|
|
110
|
+
| `ScanResult` | 扫描结果(含 `scanToken` 与 `fields`) |
|
|
111
|
+
| `RecognizePayload` / `RecognizeResult` | 识别入参与返回 |
|
|
112
|
+
| `FieldSuggestion` | 单条识别建议 |
|
|
113
|
+
| `ApplyInput` / `ApplyResult` | 回填入参与结果 |
|
|
114
|
+
| `AutoApplyItem` / `AutoApplyState` | 自动回填候选状态 |
|
|
115
|
+
| `ApiRecognizeCallbackResult` / `ApiRecognizeField` | API 回调模式返回结构 |
|
|
116
|
+
| `SmartFillEventMap` / `SmartFillError` | 事件映射与错误结构 |
|
|
117
|
+
| `SmartFillAdapter` | 自定义组件库适配器接口 |
|
|
118
|
+
| `SessionResponse` | 会话初始化响应 |
|
|
119
|
+
| `FormConfigResponse` | 已弃用的远端表单配置 |
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## SmartFill(全局入口)
|
|
124
|
+
|
|
125
|
+
### `SmartFill.setup(config): Promise<SessionResponse>`
|
|
126
|
+
|
|
127
|
+
初始化 SDK,校验 apiKey 并创建网关会话。
|
|
128
|
+
|
|
129
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
130
|
+
| --- | --- | --- | --- |
|
|
131
|
+
| `apiKey` | `string` | 是 | API 密钥,格式 `seKey-` 开头 |
|
|
132
|
+
| `requestTimeoutMs` | `number` | 否 | HTTP 超时,默认 `30000` |
|
|
133
|
+
|
|
134
|
+
行为说明:
|
|
135
|
+
|
|
136
|
+
- 相同 `apiKey` 重复调用会复用已有 Promise
|
|
137
|
+
- `apiKey` 变更时会销毁所有存活实例并清空扫描缓存
|
|
138
|
+
- SSR 环境(无 `window`)返回 mock session,不发起网络请求
|
|
139
|
+
|
|
140
|
+
### `SmartFill.create(config?): SmartFillInstance`
|
|
141
|
+
|
|
142
|
+
创建页面实例。**必须在 `setup` 就绪后调用**,否则抛出 `SDK_NOT_READY`。
|
|
143
|
+
|
|
144
|
+
SSR 环境返回 noop 实例,所有方法安全空操作。
|
|
145
|
+
|
|
146
|
+
### `SmartFill.on(event, handler): () => void`
|
|
147
|
+
|
|
148
|
+
订阅全局事件,目前仅 `ready`。返回取消订阅函数。
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## SmartFillInstance(页面实例)
|
|
153
|
+
|
|
154
|
+
通过 `SmartFill.create()` 获取,负责扫描、识别、回填与 UI 生命周期。
|
|
155
|
+
|
|
156
|
+
### 事件
|
|
157
|
+
|
|
158
|
+
#### `on(event, handler): () => void`
|
|
159
|
+
|
|
160
|
+
订阅实例事件,返回取消订阅函数。
|
|
161
|
+
|
|
162
|
+
| 事件 | 载荷 | 触发时机 |
|
|
163
|
+
| --- | --- | --- |
|
|
164
|
+
| `ready` | `{ apiKey }` | 实例就绪(全局 setup 完成时由全局总线触发) |
|
|
165
|
+
| `scanCompleted` | `{ scanToken, fieldCount }` | `rescan()` 成功 |
|
|
166
|
+
| `recognizing` | `{ scanToken, traceId }` | 识别开始 |
|
|
167
|
+
| `recognized` | `RecognizeResult` | 识别完成 |
|
|
168
|
+
| `applying` | `{ scanToken, count }` | 回填开始 |
|
|
169
|
+
| `applied` | `ApplyResult` | 回填完成 |
|
|
170
|
+
| `error` | `SmartFillError` | 任意阶段出错 |
|
|
171
|
+
|
|
172
|
+
### 字段注册
|
|
173
|
+
|
|
174
|
+
#### `registerFields(fields): this`
|
|
175
|
+
|
|
176
|
+
显式注册字段映射(L3 模式)。注册后 `rescan` 仅解析这些字段,不再自动扫 DOM。
|
|
177
|
+
|
|
178
|
+
- 支持链式调用
|
|
179
|
+
- `rowKey` 用于明细行等同 `fieldId` 多行场景,组合键 `{fieldId}:{rowKey}` 不可重复
|
|
180
|
+
|
|
181
|
+
#### `unregisterFields(fieldIds?): void`
|
|
182
|
+
|
|
183
|
+
取消注册字段。不传 `fieldIds` 时清空全部注册。
|
|
184
|
+
|
|
185
|
+
### UI 挂载
|
|
186
|
+
|
|
187
|
+
#### `mount(target): this`
|
|
188
|
+
|
|
189
|
+
将面板嵌入指定容器(inline 模式)。`target` 支持 CSS 选择器或 `HTMLElement`。
|
|
190
|
+
|
|
191
|
+
#### `mountFloatingButton(): this`
|
|
192
|
+
|
|
193
|
+
挂载右下角悬浮按钮 + 弹框(floating 模式)。挂载容器优先级见 [悬浮挂载策略](#悬浮挂载策略)。
|
|
194
|
+
|
|
195
|
+
#### `open(targetPanel?): Promise<void>`
|
|
196
|
+
|
|
197
|
+
打开面板并触发 `rescan`(若尚无扫描结果)。同时激活当前实例,关闭其他实例面板。
|
|
198
|
+
|
|
199
|
+
#### `close(targetPanel?): void`
|
|
200
|
+
|
|
201
|
+
关闭面板,不销毁实例。
|
|
202
|
+
|
|
203
|
+
### 扫描 / 识别 / 回填
|
|
204
|
+
|
|
205
|
+
#### `rescan(): Promise<ScanResult>`
|
|
206
|
+
|
|
207
|
+
扫描页面可回填字段。优先级:`registerFields` > DOM 自动扫描。
|
|
208
|
+
|
|
209
|
+
- 生成唯一 `scanToken`,贯穿识别与回填
|
|
210
|
+
- 无字段时抛出 `NO_FIELDS_FOUND`
|
|
211
|
+
- 成功时 emit `scanCompleted`
|
|
212
|
+
|
|
213
|
+
#### `recognize(input): Promise<RecognizeResult>`
|
|
214
|
+
|
|
215
|
+
识别入口:文本和/或图片 → 本地规则 + 后端网关 → 合并 → 自动回填或 API 回调。
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
await smartFill.recognize({
|
|
219
|
+
text: '姓名:张三 手机号:13800000000',
|
|
220
|
+
images: [file] // 可选,File[]
|
|
221
|
+
})
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
识别策略:
|
|
225
|
+
|
|
226
|
+
1. 识别前先 `rescan()`,下拉选项在用户主动识别时动态展开
|
|
227
|
+
2. `localRuleMode === 'off'` 跳过本地规则;`'only'` 跳过后端;`'inherit'` 跟随本地优先开关
|
|
228
|
+
3. 后端成功时优先采用后端字段,本地规则仅补充后端未返回的字段
|
|
229
|
+
4. 后端失败且存在本地结果时降级为本地识别
|
|
230
|
+
5. `apiEnable: true` 时跳过自动回填,改为触发 `apiCallback`
|
|
231
|
+
6. 置信度 ≥ 0.75 且无 `warnings` 的字段自动回填
|
|
232
|
+
|
|
233
|
+
#### `apply(input): Promise<ApplyResult>`
|
|
234
|
+
|
|
235
|
+
手动回填指定字段,需传入与当前扫描一致的 `scanToken`。
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
await smartFill.apply({
|
|
239
|
+
scanToken: result.scanToken,
|
|
240
|
+
values: [
|
|
241
|
+
{ fieldId: 'customerName', value: '张三', source: 'ai' }
|
|
242
|
+
]
|
|
243
|
+
})
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
#### `useAdapter(adapter): this`
|
|
247
|
+
|
|
248
|
+
注册组件库回填适配器,支持链式调用。实例默认已内置 `UiFrameworkAdapter`。
|
|
249
|
+
|
|
250
|
+
#### `destroy(): void`
|
|
251
|
+
|
|
252
|
+
销毁实例:移除面板、清空事件、从实例管理器注销。销毁后调用其他方法抛出 `INSTANCE_DESTROYED`。
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## SmartFill.create 配置项
|
|
257
|
+
|
|
258
|
+
| 字段 | 类型 | 默认 | 说明 |
|
|
259
|
+
| --- | --- | --- | --- |
|
|
260
|
+
| `formCode` | `string` | — | 表单编码,识别请求携带给后端 |
|
|
261
|
+
| `strictFormConfig` | `boolean` | — | **已弃用**,不再拉取远端 formConfig |
|
|
262
|
+
| `root` | `HTMLElement \| ShadowRoot` | `document` | 扫描根节点 |
|
|
263
|
+
| `maxFields` | `number` | `200` | DOM 自动扫描最大字段数 |
|
|
264
|
+
| `floatingContainer` | `HTMLElement \| string` | — | 悬浮面板挂载容器,优先级最高 |
|
|
265
|
+
| `routeContainerSelector` | `string` | — | 子路由页面容器选择器 |
|
|
266
|
+
| `locale` | `'zh-CN' \| 'en-US'` | — | 预留 |
|
|
267
|
+
| `messages` | `Record<string, string>` | — | 面板文案覆盖,key 见下表 |
|
|
268
|
+
| `apiEnable` | `boolean` | `false` | 为 `true` 时识别后不自动回填,改走 `apiCallback` |
|
|
269
|
+
| `apiCallback` | `(result) => void \| Promise<void>` | — | API 回调,仅在 `apiEnable: true` 时触发 |
|
|
270
|
+
|
|
271
|
+
### 面板文案 key(`messages`)
|
|
272
|
+
|
|
273
|
+
| key | 默认文案 |
|
|
274
|
+
| --- | --- |
|
|
275
|
+
| `entry` | 智能录入 |
|
|
276
|
+
| `title` | 智能录入 |
|
|
277
|
+
| `expand` / `collapse` / `close` | 展开 / 收起 / 关闭 |
|
|
278
|
+
| `placeholder` | 粘贴文本,如:姓名:张三 手机号:13800000000 |
|
|
279
|
+
| `clear` | 清空 |
|
|
280
|
+
| `recognize` | 智能识别 |
|
|
281
|
+
| `uploadHint` | 点击、拖拽、Ctrl + V 粘贴图片至此 |
|
|
282
|
+
| `empty` | 暂无识别结果 |
|
|
283
|
+
| `emptyInput` | 请输入文本内容。 |
|
|
284
|
+
| `recognized` | 识别完成,正在自动回填... |
|
|
285
|
+
| `invalidImageError` | 请选择图片文件。 |
|
|
286
|
+
| `maxFilesError` | 最多上传 N 张图片 |
|
|
287
|
+
| `maxSingleFileSizeError` | 单张图片不能超过 10MB |
|
|
288
|
+
| `maxTotalFileSizeError` | 上传图片总大小不能超过 50MB |
|
|
289
|
+
| `imageReady` | 已选择 N 张图片,开始识别... |
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## API 回调模式
|
|
294
|
+
|
|
295
|
+
适用于业务方自行处理识别结果、不依赖 SDK 自动 DOM 回填的场景。
|
|
296
|
+
|
|
297
|
+
```ts
|
|
298
|
+
const smartFill = SmartFill.create({
|
|
299
|
+
formCode: 'apply-form',
|
|
300
|
+
apiEnable: true,
|
|
301
|
+
apiCallback: async (result) => {
|
|
302
|
+
console.log(result.fields) // ApiRecognizeField[]
|
|
303
|
+
// 可选:自行调用 apply 回填
|
|
304
|
+
await smartFill.apply({
|
|
305
|
+
scanToken: result.scanToken,
|
|
306
|
+
values: result.fields.map((f) => ({ fieldId: f.fieldId, value: f.value }))
|
|
307
|
+
})
|
|
308
|
+
}
|
|
309
|
+
})
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
`ApiRecognizeCallbackResult` 结构:
|
|
313
|
+
|
|
314
|
+
| 字段 | 说明 |
|
|
315
|
+
| --- | --- |
|
|
316
|
+
| `scanToken` | 当前扫描批次 token |
|
|
317
|
+
| `trace` | 追踪信息(traceId、usedOcr、usedAi、durationMs) |
|
|
318
|
+
| `fields` | 识别字段列表(含 value、confidence、currentValue 等) |
|
|
319
|
+
| `warnings` | 可选警告 |
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## 扩展模块 API
|
|
324
|
+
|
|
325
|
+
### DomScanner
|
|
326
|
+
|
|
327
|
+
```ts
|
|
328
|
+
const scanner = new DomScanner(document)
|
|
329
|
+
|
|
330
|
+
// 同步扫描
|
|
331
|
+
const result = scanner.scan({
|
|
332
|
+
registered?: FieldSchema[],
|
|
333
|
+
scanContainer?: string,
|
|
334
|
+
maxFields?: number
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
// 异步扫描(展开下拉并补充动态选项)
|
|
338
|
+
const resultWithOptions = await scanner.scanWithDynamicOptions({ maxFields: 200 })
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
返回 `ScanResult`:`{ scanToken, fields: FieldDescriptor[] }`。
|
|
342
|
+
|
|
343
|
+
### DomFiller
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
const filler = new DomFiller(fields, schemas, adapters)
|
|
347
|
+
const result = await filler.apply({
|
|
348
|
+
scanToken: 'scan_xxx',
|
|
349
|
+
values: [{ fieldId: 'mobile', value: '13800000000' }]
|
|
350
|
+
})
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
回填前校验 `scanToken` 与 `fingerprint`,支持 `FieldSchema.setValue` / 适配器 / 原生 DOM 三种写入路径。
|
|
354
|
+
|
|
355
|
+
跳过原因码:`FIELD_NOT_FOUND` | `SCAN_TOKEN_EXPIRED` | `VALIDATE_FAILED` | `SET_VALUE_FAILED`。
|
|
356
|
+
|
|
357
|
+
### LocalRuleEngine
|
|
358
|
+
|
|
359
|
+
```ts
|
|
360
|
+
const engine = new LocalRuleEngine()
|
|
361
|
+
const suggestions = engine.recognize(text, fields, scanToken)
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
当前支持的本地识别类型:手机号、身份证、邮箱、银行卡、金额、日期。
|
|
365
|
+
|
|
366
|
+
### EventBus
|
|
367
|
+
|
|
368
|
+
```ts
|
|
369
|
+
const bus = new EventBus()
|
|
370
|
+
const off = bus.on('recognized', (payload) => { ... })
|
|
371
|
+
bus.off('recognized', handler)
|
|
372
|
+
bus.emit('recognized', result)
|
|
373
|
+
bus.clear()
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### SmartFillAdapter(自定义适配器)
|
|
377
|
+
|
|
378
|
+
```ts
|
|
379
|
+
smartFill.useAdapter({
|
|
380
|
+
name: 'my-component',
|
|
381
|
+
match: (element, field) => element.classList.contains('my-input'),
|
|
382
|
+
getValue: (field) => { ... },
|
|
383
|
+
setValue: async (field, value) => { ... },
|
|
384
|
+
validateApplied: async (field, value) => true
|
|
385
|
+
})
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## FieldSchema 字段注册
|
|
391
|
+
|
|
392
|
+
| 字段 | 类型 | 说明 |
|
|
393
|
+
| --- | --- | --- |
|
|
394
|
+
| `fieldId` | `string` | 字段唯一标识 |
|
|
395
|
+
| `label` | `string` | 展示标签 |
|
|
396
|
+
| `type` | `FieldType` | `text` / `textarea` / `select` / `radio` / `checkbox` / `date` / `number` / `amount` / `cascader` |
|
|
397
|
+
| `element` | `HTMLElement \| string` | DOM 元素或 CSS 选择器 |
|
|
398
|
+
| `localRuleMode` | `'inherit' \| 'off' \| 'only'` | 本地规则策略 |
|
|
399
|
+
| `options` | `FieldOption[]` | 下拉/单选选项 |
|
|
400
|
+
| `getValue` | `() => unknown` | 自定义读值 |
|
|
401
|
+
| `setValue` | `(value) => void \| Promise<void>` | 自定义写值 |
|
|
402
|
+
| `transform` | `(aiValue) => unknown` | AI 返回值转换 |
|
|
403
|
+
| `validate` | `(value) => boolean \| string \| Promise<...>` | 写入前校验 |
|
|
404
|
+
| `rowKey` | `string \| number` | 明细行 key |
|
|
405
|
+
| `scope` | `'form' \| 'detail' \| 'dialog'` | 字段作用域 |
|
|
406
|
+
| `required` / `section` / `demoValue` | — | 其他元数据 |
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## 本地规则
|
|
411
|
+
|
|
412
|
+
| 层级 | 配置 | 说明 |
|
|
413
|
+
| --- | --- | --- |
|
|
414
|
+
| 实例级 | `localPriorityEnabled`(localStorage 持久化) | 默认 **关闭**(优先后端识别);开启后 `inherit` 字段走本地规则 |
|
|
415
|
+
| 字段级 | `FieldSchema.localRuleMode` | `inherit` 跟随实例开关;`off` 跳过后端;`only` 仅本地、不走后端 |
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## 悬浮挂载策略
|
|
420
|
+
|
|
421
|
+
`mountFloatingButton()` 挂载容器优先级:
|
|
422
|
+
|
|
423
|
+
1. `floatingContainer`:显式指定容器(`HTMLElement` 或 CSS 选择器)
|
|
424
|
+
2. `routeContainerSelector`:子路由页面容器
|
|
425
|
+
3. SDK 自动识别(`#app` / `#root` / `main` / `.page-container` 等)
|
|
426
|
+
4. 回退到 `document.body`
|
|
427
|
+
|
|
428
|
+
floating 模式下路由切换或挂载容器从 DOM 移除时,实例会自动 `destroy()`。
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## 错误码
|
|
433
|
+
|
|
434
|
+
| code | stage | 说明 |
|
|
435
|
+
| --- | --- | --- |
|
|
436
|
+
| `SDK_NOT_READY` | setup | 未调用 setup 或 setup 未完成 |
|
|
437
|
+
| `API_KEY_INVALID` | setup | apiKey 格式不正确 |
|
|
438
|
+
| `NO_FIELDS_FOUND` | scan | 当前页面未找到可回填字段 |
|
|
439
|
+
| `UNSUPPORTED_PAGE` | scan / ui | 字段重复注册 / 挂载点未找到 |
|
|
440
|
+
| `SCAN_TOKEN_EXPIRED` | apply | 扫描已过期,需重新 rescan |
|
|
441
|
+
| `TOKEN_EXPIRED` | recognize | 会话过期,清空扫描缓存 |
|
|
442
|
+
| `INSTANCE_DESTROYED` | ui | 实例已销毁 |
|
|
443
|
+
| `RECOGNIZE_FAILED` | recognize | 识别失败 |
|
|
444
|
+
| `RECOGNIZE_TIMEOUT` | recognize | 识别超时(可重试) |
|
|
445
|
+
|
|
446
|
+
捕获示例:
|
|
447
|
+
|
|
448
|
+
```ts
|
|
449
|
+
import { SmartFillException } from '@kc-one/smart-fill-sdk'
|
|
450
|
+
|
|
451
|
+
try {
|
|
452
|
+
await smartFill.recognize({ text: '...' })
|
|
453
|
+
} catch (error) {
|
|
454
|
+
if (error instanceof SmartFillException) {
|
|
455
|
+
console.log(error.smartFillError.code, error.smartFillError.traceId)
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## 目录结构
|
|
463
|
+
|
|
464
|
+
```text
|
|
465
|
+
smart-fill-sdk/
|
|
466
|
+
├─ package.json
|
|
467
|
+
├─ vite.config.ts
|
|
468
|
+
├─ tsconfig.json
|
|
469
|
+
├─ README.md
|
|
470
|
+
│
|
|
471
|
+
├─ examples/vanilla/ # 原生表单接入示例
|
|
472
|
+
│ ├─ index.html
|
|
473
|
+
│ └─ main.ts
|
|
474
|
+
│
|
|
475
|
+
└─ src/
|
|
476
|
+
├─ index.ts # 包入口,统一导出 API 与类型
|
|
477
|
+
├─ style.css # 回填高亮样式
|
|
478
|
+
│
|
|
479
|
+
├─ core/ # 生命周期与实例编排
|
|
480
|
+
│ ├─ smart-fill.ts # setup / create 全局入口
|
|
481
|
+
│ ├─ smart-fill-instance.ts
|
|
482
|
+
│ ├─ instance-manager.ts # 多实例 UI 互斥
|
|
483
|
+
│ └─ errors.ts # SmartFillException / createError
|
|
484
|
+
│
|
|
485
|
+
├─ scanner/ # 字段扫描
|
|
486
|
+
│ ├─ dom-scanner.ts
|
|
487
|
+
│ ├─ fingerprint.ts
|
|
488
|
+
│ └─ ui-frameworks.ts # Element / AntD / Naive 等组件识别
|
|
489
|
+
│
|
|
490
|
+
├─ select/ # 下拉 / 级联 / 地址选择回填
|
|
491
|
+
│ ├─ custom-select.ts
|
|
492
|
+
│ ├─ select-fill.ts
|
|
493
|
+
│ ├─ option-match.ts
|
|
494
|
+
│ └─ address-cascader.ts
|
|
495
|
+
│
|
|
496
|
+
├─ rules/local-rules.ts # 本地规则引擎
|
|
497
|
+
├─ config/defaults.ts # DEFAULT_BASE_URL
|
|
498
|
+
├─ client/gateway-client.ts # 网关 HTTP 客户端
|
|
499
|
+
├─ filler/ # DOM 回填与高亮
|
|
500
|
+
│ ├─ dom-filler.ts
|
|
501
|
+
│ └─ highlight-style.ts
|
|
502
|
+
├─ ui/panel.ts # Shadow DOM 面板
|
|
503
|
+
├─ events/event-bus.ts
|
|
504
|
+
├─ adapters/ # 原生 + UI 框架适配器
|
|
505
|
+
│ ├─ native.ts
|
|
506
|
+
│ └─ ui-framework.ts
|
|
507
|
+
└─ types/index.ts # 全部对外 TypeScript 类型
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## 实现范围
|
|
513
|
+
|
|
514
|
+
| 模块 | 能力 |
|
|
515
|
+
| --- | --- |
|
|
516
|
+
| `SmartFill.setup` | apiKey 校验、会话初始化 |
|
|
517
|
+
| `SmartFill.create` | 实例生命周期、单活 UI 管理、SSR mock |
|
|
518
|
+
| `registerFields / rescan` | 优先注册字段,兜底 DOM 扫描 + 页面/会话级扫描缓存 |
|
|
519
|
+
| `LocalRuleEngine` | 手机号、身份证、邮箱、银行卡、金额、日期 |
|
|
520
|
+
| `FieldSchema.localRuleMode` | 字段级本地规则策略 |
|
|
521
|
+
| `SmartFillPanel` | Shadow DOM 面板、文本/图片输入、识别进度与结果反馈 |
|
|
522
|
+
| `DomFiller` | 原生 + UI 框架回填、scanToken / fingerprint 校验、浅蓝高亮 |
|
|
523
|
+
| `UiFrameworkAdapter` | Element / Ant Design Vue / Naive UI / Arco / Vant 等 |
|
|
524
|
+
| `GatewayClient` | session / OCR / smartEntry 识别网关 |
|
|
525
|
+
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
## 构建与发布
|
|
529
|
+
|
|
530
|
+
```bash
|
|
531
|
+
npm run typecheck # 类型检查
|
|
532
|
+
npm run build # 构建 dist/(ESM + UMD + d.ts)
|
|
533
|
+
npm run preview # 预览构建产物
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
发布到 [@kc-one](https://www.npmjs.com/settings/kc-one/packages):
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
npm login
|
|
540
|
+
npm run build
|
|
541
|
+
npm publish --access public
|
|
542
|
+
```
|