Files
scan-code-jssdk/dist/README.md
iqudoo ed1ee040cc fix
2026-05-01 23:11:43 +08:00

337 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# scan-code-jssdk
统一扫码 JSSDK支持桥接扫码、微信小程序、微信 JSSDK 扫码、Web 摄像头扫码、选择图片识别和扫码枪输入。
## 功能
- App 桥接环境:优先调用原生桥接 `startScan` / `stopScan`
- 微信浏览器:初始化微信 JSSDK 后调用 `wx.scanQRCode`
- Web 浏览器:使用 `BarcodeDetector` 识别二维码和条形码。
- 图片识别:选择本地图片后识别二维码/条形码。
- 扫码枪:监听键盘快速输入并统一走扫码监听回调。
- 监听规则:支持按 `match` 正则和 `level` 优先级分发扫码结果。
## 引入
构建后使用 `dist/index.js`
```html
<script src="./dist/index.js"></script>
<script>
IScan.config().then(function () {
console.log("IScan ready");
});
</script>
```
如果脚本是后加载的,可以监听 `IScanReady`
```js
function init() {
IScan.config().then(function () {
// ready
});
}
if (window.IScan) {
init();
} else {
window.addEventListener("IScanReady", init, { once: true });
}
```
## 快速开始
```js
IScan.config({
initWechatJssdk: {
apiUrl: "https://your-domain.com/wechat/jssdk-config"
}
}).then(function () {
// 监听识别状态
IScan.setStatusListener(function (status) {
console.log("status:", status);
});
// 监听识别结果
IScan.onScanListener(function (res) {
console.log("scan result:", res.result, res.key);
}, "scan", null, 100);
});
// 自动选择可用扫码方式:桥接 -> 微信 -> Web 摄像头 -> 图片识别
IScan.startScan();
// 仅打开 Web 视频扫码
IScan.scanVideo();
// 仅选择图片识别
IScan.scanImage();
// 停止当前扫码
IScan.stopScan();
```
## 配置项
通过 `IScan.config(options)` 配置。
```ts
interface ScanConfigOptions {
scanRestartDelay?: number,
bridgeEnabled?: boolean;
bridgeName?: string;
webScanEnabled?: boolean,
webScanCanvasEnabled?: boolean;
webScanCanvasStyle?: string;
webScanCloseButtonStyle?: string;
webScanType?: ("qrCode" | "barCode")[];
webScanVideoMirror?: boolean;
webScanVideoMirrorVertical?: boolean;
webScanBeepAudio?: string;
webScanBeepEnabled?: boolean;
initWechatJssdk?: {
apiUrl?: string;
sdkConfig?: {
debug?: boolean;
appId: string;
timestamp: number;
nonceStr: string;
signature: string;
};
sdkUrl?: string;
jsApiList?: string[];
};
}
```
| 配置 | 说明 | 默认值 |
| --- | --- | --- |
| `scanRestartDelay` | 扫码重启延迟,单位:毫秒 | `500ms` |
| `bridgeEnabled` | 是否启用桥接扫码 | `true` |
| `bridgeName` | 挂载在 `window` 上的桥接对象名称 | `__bridge_client__` |
| `webScanEnabled` | 是否支持 WebScan 扫码 | `true` |
| `webScanCanvasEnabled` | 是否显示 WebScan 扫码 canvas关闭后仍会用隐藏 canvas 识别 | `true` |
| `webScanCanvasStyle` | WebScan 扫码 canvas 样式 | `position: fixed; width: 300px; height: 300px; top: 0; left: 0; z-index: 9999;` |
| `webScanCloseButtonStyle` | WebScan 扫码 canvas 关闭按钮样式 | 显示在 canvas 右上角 |
| `webScanType` | WebScan 扫码类型 | `["qrCode", "barCode"]` |
| `webScanVideoMirror` | WebScan 视频是否水平镜像;不配置时自动判断:前置/PC 镜像,后置不镜像 | 自动 |
| `webScanVideoMirrorVertical` | WebScan 视频是否垂直镜像 | `false` |
| `webScanBeepAudio` | WebScan 扫码成功提示音地址 | 内置提示音 |
| `webScanBeepEnabled` | WebScan 扫码成功是否播放提示音 | `true` |
| `initWechatJssdk` | 微信 JSSDK 初始化配置,仅微信环境生效 | 无 |
`initWechatJssdk` 子配置:
| 配置 | 说明 | 默认值 |
| --- | --- | --- |
| `apiUrl` | 微信 JSSDK 签名配置接口地址;未传 `sdkConfig` 时会请求该接口,并自动携带当前页面 URL 参数 | 无 |
| `sdkConfig` | 直接传入微信 JSSDK 签名配置;配置后不再请求 `apiUrl` | 无 |
| `sdkConfig.debug` | 是否开启微信 JSSDK 调试模式 | `false` |
| `sdkConfig.appId` | 微信公众平台应用 ID | 必填 |
| `sdkConfig.timestamp` | 签名时间戳 | 必填 |
| `sdkConfig.nonceStr` | 签名随机字符串 | 必填 |
| `sdkConfig.signature` | 微信 JSSDK 签名 | 必填 |
| `sdkUrl` | 微信 JSSDK 脚本地址 | `https://res.wx.qq.com/open/js/jweixin-1.6.0.js` |
| `jsApiList` | 微信 JSSDK JS-API 列表SDK 会自动追加 `scanQRCode` | `["scanQRCode"]` |
## 桥接接入
桥接对象需要挂载到 `window[bridgeName]`,并实现 `call(method, data)`
SDK 会调用:
- `startScan`
- `stopScan`
异步回调方法名为 `${bridgeName}_handle_callback`
```js
window.__bridge_client__ = {
call: function (method, data) {
var requestId = data.request_id;
if (method === "startScan") {
// 调用原生扫码后回调
window.__bridge_client___handle_callback({
code: 0,
method: method,
request_id: requestId,
payload: {
result: "https://example.com"
}
});
}
if (method === "stopScan") {
window.__bridge_client___handle_callback({
code: 0,
method: method,
request_id: requestId,
payload: {}
});
}
}
};
```
## 微信 JSSDK 接入
配置接口方式:
```js
IScan.config({
initWechatJssdk: {
apiUrl: "https://your-domain.com/wechat/jssdk-config"
}
});
```
接口会收到当前页面 URL 参数:`url=location.href.split("#")[0]`
也可以直接传入微信签名配置:
```js
IScan.config({
initWechatJssdk: {
apiUrl: "",
sdkConfig: {
appId: "wx_app_id",
timestamp: 123456,
nonceStr: "nonce",
signature: "signature"
}
}
});
```
`jsApiList` 会默认追加 `scanQRCode`
## API
### `config(options?): Promise<any>`
配置并初始化 SDK。
```js
IScan.config({
webScanCanvasEnabled: true
});
```
### `setStatusListener(callback): void`
监听扫码状态,状态为:
- `scanning`
- `closed`
```js
IScan.setStatusListener(function (status) {
console.log(status);
});
```
### `onScanListener(callback, key, match?, level?): ScanListenerInfo`
添加扫码结果监听。
```js
var listener = IScan.onScanListener(function (res) {
console.log(res.result, res.key);
}, "order", "^https://", 100);
```
参数说明:
- `callback`:扫码结果回调。
- `key`:监听 key同 key 会覆盖旧监听。
- `match`:可选正则字符串;扫码结果匹配后才回调。
- `level`:优先级,数值越大越先匹配。
### `offScanListener(callbackOrKey): void`
移除监听,可传 callback 或 key。
```js
IScan.offScanListener("order");
listener.cancel();
```
### `getStatus(): "scanning" | "ready"`
获取当前扫码状态。
```js
console.log(IScan.getStatus());
```
### `startScan(): void`
开启扫码。SDK 会按以下顺序选择可用能力:
1. 桥接扫码
2. 微信扫码
3. Web 摄像头扫码
4. 图片识别
扫码结果通过 `onScanListener` 回调。
```js
IScan.startScan();
```
### `scanVideo(): void`
直接开启 Web 摄像头扫码。扫码结果通过 `onScanListener` 回调。
```js
IScan.scanVideo();
```
### `scanImage(): void`
直接选择图片进行识别。识别结果通过 `onScanListener` 回调。
```js
IScan.scanImage();
```
### `stopScan(): void`
停止当前扫码。
```js
IScan.stopScan();
```
### `clear(): void`
清空全部扫码监听。
```js
IScan.clear();
```
## 类型
```ts
interface ScanResult {
result: string;
key: string;
}
type ScanStatus = "scanning" | "ready";
type ScanResultCallback = (result: ScanResult) => any;
type ScanStatusCallback = (status: ScanStatus) => any;
```
## 开发
```bash
npm install
npm run build
```
构建产物输出到 `dist` 目录。