@kc-one/smart-fill-sdk
v0.0.19
Published
Page-embedded smart form filling SDK.
Downloads
439
Readme
Smart Fill SDK
页面内智能录入 SDK,用于在业务页面嵌入「文本 / 图片识别 → 自动表单回填 → 结果反馈」能力。
- 包名:
@kc-one/smart-fill-sdk - 当前版本:
0.0.12 - 浏览器:Chrome ≥ 90、Edge ≥ 90、Firefox ≥ 88、Safari ≥ 14
安装
npm install @kc-one/smart-fill-sdk快速开始
本地开发
npm install
npm run dev打开 Vite 示例页(examples/vanilla/index.html),点击「智能录入」入口。
业务接入
import { SmartFill } from '@kc-one/smart-fill-sdk'
import '@kc-one/smart-fill-sdk/style.css'
await SmartFill.setup({ apiKey: 'seKey-xxxxxxxxxxxxx' })
// 网关根地址见 DEFAULT_BASE_URL(src/config/defaults.ts)
const smartFill = SmartFill.create({
formCode: 'apply-form',
routeContainerSelector: '.page-container'
})
smartFill.registerFields([
{
fieldId: 'customerName',
label: '客户姓名',
type: 'text',
element: '[data-smart-fill-key="customerName"]'
},
{
fieldId: 'legalBankMobile',
label: '法人手机号',
type: 'text',
localRuleMode: 'off', // 该字段不走本地规则,仅走后端识别
element: '[data-smart-fill-key="legalBankMobile"]'
}
])
smartFill.mountFloatingButton()
// 或嵌入指定容器:smartFill.mount('#smart-fill-entry')核心流程
SmartFill.setup({ apiKey })
→ 校验 apiKey / 创建会话 / 获取 accessToken
SmartFill.create({ formCode, ... })
→ 创建页面实例,绑定网关客户端
smartFill.registerFields([...]) // 可选:L3 高精度字段注册
smartFill.mountFloatingButton() // 或 mount() 嵌入容器
smartFill.open() // 打开面板并 rescan
用户输入文本 / 上传图片,点击「智能识别」
→ rescan() 扫描字段,生成 scanToken
→ 本地规则预识别(可开关)
→ 后端识别网关补全
→ 合并结果,自动回填高置信字段(或 apiCallback 回调)
→ 返回 applied / skipped / warnings / traceId对外 API 总览
类与常量
| 导出 | 说明 |
| --- | --- |
| SmartFill | 全局入口:setup / create / on |
| SmartFillInstance | 页面实例类(通常通过 SmartFill.create() 获取) |
| DomScanner | DOM 字段扫描器 |
| DomFiller | 表单回填执行器 |
| LocalRuleEngine | 浏览器端本地规则识别引擎 |
| EventBus | 轻量事件总线 |
| NativeAdapter | 原生 input / textarea / select 适配器 |
| UiFrameworkAdapter | Element / Ant Design Vue / Naive UI / Arco / Vant 等 UI 框架适配器 |
| ElementAdapter | UiFrameworkAdapter 的兼容别名 |
| DEFAULT_BASE_URL | 网关根地址常量 |
| SmartFillException | 结构化异常类 |
| createError | 创建标准 SDK 异常 |
| toSmartFillError | 将未知 error 归一化为 SmartFillError |
| createTraceId | 生成唯一追踪 ID |
类型
| 类型 | 说明 |
| --- | --- |
| SmartFillSetupConfig | setup() 配置 |
| SmartFillCreateConfig | create() 配置 |
| FieldSchema | 业务注册字段 Schema |
| FieldDescriptor | 扫描后的运行时字段描述 |
| FieldType / FieldOption | 字段类型与选项 |
| ScanResult | 扫描结果(含 scanToken 与 fields) |
| RecognizePayload / RecognizeResult | 识别入参与返回 |
| FieldSuggestion | 单条识别建议 |
| ApplyInput / ApplyResult | 回填入参与结果 |
| AutoApplyItem / AutoApplyState | 自动回填候选状态 |
| ApiRecognizeCallbackResult / ApiRecognizeField | API 回调模式返回结构 |
| SmartFillEventMap / SmartFillError | 事件映射与错误结构 |
| SmartFillAdapter | 自定义组件库适配器接口 |
| SessionResponse | 会话初始化响应 |
| FormConfigResponse | 已弃用的远端表单配置 |
SmartFill(全局入口)
SmartFill.setup(config): Promise<SessionResponse>
初始化 SDK,校验 apiKey 并创建网关会话。
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| apiKey | string | 是 | API 密钥,格式 seKey- 开头 |
| requestTimeoutMs | number | 否 | HTTP 超时,默认 30000 |
行为说明:
- 相同
apiKey重复调用会复用已有 Promise apiKey变更时会销毁所有存活实例并清空扫描缓存- SSR 环境(无
window)返回 mock session,不发起网络请求
SmartFill.create(config?): SmartFillInstance
创建页面实例。必须在 setup 就绪后调用,否则抛出 SDK_NOT_READY。
SSR 环境返回 noop 实例,所有方法安全空操作。
SmartFill.on(event, handler): () => void
订阅全局事件,目前仅 ready。返回取消订阅函数。
SmartFillInstance(页面实例)
通过 SmartFill.create() 获取,负责扫描、识别、回填与 UI 生命周期。
事件
on(event, handler): () => void
订阅实例事件,返回取消订阅函数。
| 事件 | 载荷 | 触发时机 |
| --- | --- | --- |
| ready | { apiKey } | 实例就绪(全局 setup 完成时由全局总线触发) |
| scanCompleted | { scanToken, fieldCount } | rescan() 成功 |
| recognizing | { scanToken, traceId } | 识别开始 |
| recognized | RecognizeResult | 识别完成 |
| applying | { scanToken, count } | 回填开始 |
| applied | ApplyResult | 回填完成 |
| error | SmartFillError | 任意阶段出错 |
字段注册
registerFields(fields): this
显式注册字段映射(L3 模式)。注册后 rescan 仅解析这些字段,不再自动扫 DOM。
- 支持链式调用
rowKey用于明细行等同fieldId多行场景,组合键{fieldId}:{rowKey}不可重复
unregisterFields(fieldIds?): void
取消注册字段。不传 fieldIds 时清空全部注册。
UI 挂载
mount(target): this
将面板嵌入指定容器(inline 模式)。target 支持 CSS 选择器或 HTMLElement。
可通过 panelInitialOpen、inlineHideOuterFrame 调整嵌入面板初始展开状态与是否隐藏外边框,详见 嵌入模式 UI 配置。
mountFloatingButton(): this
挂载右下角悬浮按钮 + 弹框(floating 模式)。挂载容器优先级见 悬浮挂载策略。
open(targetPanel?): Promise<void>
打开面板并触发 rescan(若尚无扫描结果)。同时激活当前实例,关闭其他实例面板。
close(targetPanel?): void
关闭面板,不销毁实例。
扫描 / 识别 / 回填
rescan(): Promise<ScanResult>
扫描页面可回填字段。优先级:registerFields > DOM 自动扫描。
- 生成唯一
scanToken,贯穿识别与回填 - 无字段时抛出
NO_FIELDS_FOUND - 成功时 emit
scanCompleted
recognize(input): Promise<RecognizeResult>
识别入口:文本和/或图片 → 本地规则 + 后端网关 → 合并 → 自动回填或 API 回调。
await smartFill.recognize({
text: '姓名:张三 手机号:13800000000',
images: [file] // 可选,File[]
})识别策略:
- 识别前先
rescan(),下拉选项在用户主动识别时动态展开 localRuleMode === 'off'跳过本地规则;'only'跳过后端;'inherit'跟随本地优先开关- 后端成功时优先采用后端字段,本地规则仅补充后端未返回的字段
- 后端失败且存在本地结果时降级为本地识别
apiEnable: true时跳过自动回填,改为触发apiCallback- 置信度 ≥ 0.75 且无
warnings的字段自动回填
apply(input): Promise<ApplyResult>
手动回填指定字段,需传入与当前扫描一致的 scanToken。
await smartFill.apply({
scanToken: result.scanToken,
values: [
{ fieldId: 'customerName', value: '张三', source: 'ai' }
]
})useAdapter(adapter): this
注册组件库回填适配器,支持链式调用。实例默认已内置 UiFrameworkAdapter。
destroy(): void
销毁实例:移除面板、清空事件、从实例管理器注销。销毁后调用其他方法抛出 INSTANCE_DESTROYED。
SmartFill.create 配置项
| 字段 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| formCode | string | — | 表单编码,识别请求携带给后端 |
| strictFormConfig | boolean | — | 已弃用,不再拉取远端 formConfig |
| root | HTMLElement \| ShadowRoot | document | 扫描根节点 |
| maxFields | number | 200 | DOM 自动扫描最大字段数 |
| floatingContainer | HTMLElement \| string | — | 悬浮面板挂载容器,优先级最高 |
| routeContainerSelector | string | — | 子路由页面容器选择器 |
| floatingOffsetTop | number \| string | 30 | 仅 mountFloatingButton() 生效;悬浮入口距顶部间距,number 按 px 处理 |
| floatingOffsetRight | number \| string | 30 | 仅 mountFloatingButton() 生效;悬浮入口距右侧间距,number 按 px 处理 |
| floatingButtonStyle | SmartFillFloatingButtonStyle | — | 仅 mountFloatingButton() 生效;支持背景、字体、圆角、阴影等样式覆盖 |
| locale | 'zh-CN' \| 'en-US' | — | 预留 |
| messages | Record<string, string> | — | 面板文案覆盖,key 见下表 |
| panelInitialOpen | boolean | true | 面板首次进入时的默认展开状态;仅在当前页面对应 localStorage 尚无展开状态缓存时生效 |
| inlineHideOuterFrame | boolean | false | 仅 mount() 嵌入模式生效;true 时隐藏外边框和标题栏,仅保留输入内容区域 |
| apiEnable | boolean | false | 为 true 时识别后不自动回填,改走 apiCallback |
| apiCallback | (result) => void \| Promise<void> | — | API 回调,仅在 apiEnable: true 时触发 |
嵌入模式 UI 配置
通过 mount() 嵌入页面时,可用以下字段控制面板外观与初始展开状态(对 mountFloatingButton() 悬浮模式无效):
| 字段 | 默认 | 效果 |
| --- | --- | --- |
| panelInitialOpen | true | false 时首次进入默认收起;用户手动展开/收起后会写入 localStorage,后续访问以缓存为准 |
| inlineHideOuterFrame | false | true 时移除外层边框、背景与「智能录入」标题栏,仅展示文本输入区、图片上传区及底部状态文案 |
const smartFill = SmartFill.create({
panelInitialOpen: false, // 首次进入默认收起
inlineHideOuterFrame: true // 隐藏外边框与标题,仅保留内容区
})
smartFill.mount('#smart-fill-entry')悬浮模式 UI 配置
通过 mountFloatingButton() 挂载时,可用以下字段调整入口按钮位置和样式:
const smartFill = SmartFill.create({
floatingOffsetTop: 20, // number 表示 px,也可传 '2rem'
floatingOffsetRight: 24,
floatingButtonStyle: {
background: 'linear-gradient(90deg, #FF7E49 0%, #FFA34E 100%)',
color: '#fff',
borderRadius: '999px',
padding: '10px 30px',
fontSize: '15px',
boxShadow: '0 10px 24px rgba(37, 99, 235, 0.3)'
}
})
smartFill.mountFloatingButton()面板文案 key(messages)
| key | 默认文案 |
| --- | --- |
| entry | 智能录入 |
| title | 智能录入 |
| expand / collapse / close | 展开 / 收起 / 关闭 |
| placeholder | 粘贴文本,如:姓名:张三 手机号:13800000000 |
| clear | 清空 |
| recognize | 智能识别 |
| uploadHint | 点击、拖拽、Ctrl + V 粘贴图片至此 |
| empty | 暂无识别结果 |
| emptyInput | 请输入文本内容。 |
| recognized | 识别完成,正在自动回填... |
| invalidImageError | 请选择图片文件。 |
| maxFilesError | 最多上传 N 张图片 |
| maxSingleFileSizeError | 单张图片不能超过 10MB |
| maxTotalFileSizeError | 上传图片总大小不能超过 50MB |
| imageReady | 已选择 N 张图片,开始识别... |
API 回调模式
适用于业务方自行处理识别结果、不依赖 SDK 自动 DOM 回填的场景。
const smartFill = SmartFill.create({
formCode: 'apply-form',
apiEnable: true,
apiCallback: async (result) => {
console.log(result.fields) // ApiRecognizeField[]
// 可选:自行调用 apply 回填
await smartFill.apply({
scanToken: result.scanToken,
values: result.fields.map((f) => ({ fieldId: f.fieldId, value: f.value }))
})
}
})ApiRecognizeCallbackResult 结构:
| 字段 | 说明 |
| --- | --- |
| scanToken | 当前扫描批次 token |
| trace | 追踪信息(traceId、usedOcr、usedAi、durationMs) |
| fields | 识别字段列表(含 value、confidence、currentValue 等) |
| warnings | 可选警告 |
扩展模块 API
DomScanner
const scanner = new DomScanner(document)
// 同步扫描
const result = scanner.scan({
registered?: FieldSchema[],
scanContainer?: string,
maxFields?: number
})
// 异步扫描(展开下拉并补充动态选项)
const resultWithOptions = await scanner.scanWithDynamicOptions({ maxFields: 200 })返回 ScanResult:{ scanToken, fields: FieldDescriptor[] }。
DomFiller
const filler = new DomFiller(fields, schemas, adapters)
const result = await filler.apply({
scanToken: 'scan_xxx',
values: [{ fieldId: 'mobile', value: '13800000000' }]
})回填前校验 scanToken 与 fingerprint,支持 FieldSchema.setValue / 适配器 / 原生 DOM 三种写入路径。
跳过原因码:FIELD_NOT_FOUND | SCAN_TOKEN_EXPIRED | VALIDATE_FAILED | SET_VALUE_FAILED。
LocalRuleEngine
const engine = new LocalRuleEngine()
const suggestions = engine.recognize(text, fields, scanToken)当前支持的本地识别类型:手机号、身份证、邮箱、银行卡、金额、日期。
EventBus
const bus = new EventBus()
const off = bus.on('recognized', (payload) => { ... })
bus.off('recognized', handler)
bus.emit('recognized', result)
bus.clear()SmartFillAdapter(自定义适配器)
smartFill.useAdapter({
name: 'my-component',
match: (element, field) => element.classList.contains('my-input'),
getValue: (field) => { ... },
setValue: async (field, value) => { ... },
validateApplied: async (field, value) => true
})FieldSchema 字段注册
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| fieldId | string | 字段唯一标识 |
| label | string | 展示标签 |
| type | FieldType | text / textarea / select / radio / checkbox / date / number / amount / cascader |
| element | HTMLElement \| string | DOM 元素或 CSS 选择器 |
| localRuleMode | 'inherit' \| 'off' \| 'only' | 本地规则策略 |
| options | FieldOption[] | 下拉/单选选项 |
| getValue | () => unknown | 自定义读值 |
| setValue | (value) => void \| Promise<void> | 自定义写值 |
| transform | (aiValue) => unknown | AI 返回值转换 |
| validate | (value) => boolean \| string \| Promise<...> | 写入前校验 |
| rowKey | string \| number | 明细行 key |
| scope | 'form' \| 'detail' \| 'dialog' | 字段作用域 |
| required / section / demoValue | — | 其他元数据 |
本地规则
| 层级 | 配置 | 说明 |
| --- | --- | --- |
| 实例级 | localPriorityEnabled(localStorage 持久化) | 默认 关闭(优先后端识别);开启后 inherit 字段走本地规则 |
| 字段级 | FieldSchema.localRuleMode | inherit 跟随实例开关;off 跳过后端;only 仅本地、不走后端 |
悬浮挂载策略
mountFloatingButton() 挂载容器优先级:
floatingContainer:显式指定容器(HTMLElement或 CSS 选择器)routeContainerSelector:子路由页面容器- SDK 自动识别(
#app/#root/main/.page-container等) - 回退到
document.body
floating 模式下路由切换或挂载容器从 DOM 移除时,实例会自动 destroy()。
错误码
| code | stage | 说明 |
| --- | --- | --- |
| SDK_NOT_READY | setup | 未调用 setup 或 setup 未完成 |
| API_KEY_INVALID | setup | apiKey 格式不正确 |
| NO_FIELDS_FOUND | scan | 当前页面未找到可回填字段 |
| UNSUPPORTED_PAGE | scan / ui | 字段重复注册 / 挂载点未找到 |
| SCAN_TOKEN_EXPIRED | apply | 扫描已过期,需重新 rescan |
| TOKEN_EXPIRED | recognize | 会话过期,清空扫描缓存 |
| INSTANCE_DESTROYED | ui | 实例已销毁 |
| RECOGNIZE_FAILED | recognize | 识别失败 |
| RECOGNIZE_TIMEOUT | recognize | 识别超时(可重试) |
捕获示例:
import { SmartFillException } from '@kc-one/smart-fill-sdk'
try {
await smartFill.recognize({ text: '...' })
} catch (error) {
if (error instanceof SmartFillException) {
console.log(error.smartFillError.code, error.smartFillError.traceId)
}
}目录结构
smart-fill-sdk/
├─ package.json
├─ vite.config.ts
├─ tsconfig.json
├─ README.md
│
├─ examples/vanilla/ # 原生表单接入示例
│ ├─ index.html
│ └─ main.ts
│
└─ src/
├─ index.ts # 包入口,统一导出 API 与类型
├─ style.css # 回填高亮样式
│
├─ core/ # 生命周期与实例编排
│ ├─ smart-fill.ts # setup / create 全局入口
│ ├─ smart-fill-instance.ts
│ ├─ instance-manager.ts # 多实例 UI 互斥
│ └─ errors.ts # SmartFillException / createError
│
├─ scanner/ # 字段扫描
│ ├─ dom-scanner.ts
│ ├─ fingerprint.ts
│ └─ ui-frameworks.ts # Element / AntD / Naive 等组件识别
│
├─ select/ # 下拉 / 级联 / 地址选择回填
│ ├─ custom-select.ts
│ ├─ select-fill.ts
│ ├─ option-match.ts
│ └─ address-cascader.ts
│
├─ rules/local-rules.ts # 本地规则引擎
├─ config/defaults.ts # DEFAULT_BASE_URL
├─ client/gateway-client.ts # 网关 HTTP 客户端
├─ filler/ # DOM 回填与高亮
│ ├─ dom-filler.ts
│ └─ highlight-style.ts
├─ ui/panel.ts # Shadow DOM 面板
├─ events/event-bus.ts
├─ adapters/ # 原生 + UI 框架适配器
│ ├─ native.ts
│ └─ ui-framework.ts
└─ types/index.ts # 全部对外 TypeScript 类型实现范围
| 模块 | 能力 |
| --- | --- |
| SmartFill.setup | apiKey 校验、会话初始化 |
| SmartFill.create | 实例生命周期、单活 UI 管理、SSR mock |
| registerFields / rescan | 优先注册字段,兜底 DOM 扫描 + 页面/会话级扫描缓存 |
| LocalRuleEngine | 手机号、身份证、邮箱、银行卡、金额、日期 |
| FieldSchema.localRuleMode | 字段级本地规则策略 |
| SmartFillPanel | Shadow DOM 面板、文本/图片输入、识别进度与结果反馈 |
| DomFiller | 原生 + UI 框架回填、scanToken / fingerprint 校验、浅蓝高亮 |
| UiFrameworkAdapter | Element / Ant Design Vue / Naive UI / Arco / Vant 等 |
| GatewayClient | session / OCR / smartEntry 识别网关 |
构建与发布
npm run typecheck # 类型检查
npm run build # 构建 dist/(ESM + UMD + d.ts)
npm run preview # 预览构建产物发布到 @kc-one:
npm login
npm run build
npm publish --access public