优化:支持控制是否显示

This commit is contained in:
iqudoo
2026-04-30 11:17:05 +08:00
parent 8ebe8b0b34
commit f3c0856506
11 changed files with 142 additions and 26 deletions

View File

@@ -129,7 +129,11 @@
output("call ready"); output("call ready");
hide(); hide();
var url = "https://vet.iqudoo.com/api?action=api.biz.wechat.JSSDKConfig"; var url = "https://vet.iqudoo.com/api?action=api.biz.wechat.JSSDKConfig";
initSDK({ initWechatJssdk: { apiUrl: url } }, function () { initSDK({
webCanvasEnabled: true,
webScanBeepEnabled: true,
initWechatJssdk: { apiUrl: url }
}, function () {
IScan.setStatusListener(function (res) { IScan.setStatusListener(function (res) {
output("status", IScan.getStatus()); output("status", IScan.getStatus());
}); });

41
dist/index.d.ts vendored
View File

@@ -6,6 +6,22 @@ interface ScanConfigOptions {
* 网页扫码canvas样式 * 网页扫码canvas样式
*/ */
webCanvasStyle?: string, webCanvasStyle?: string,
/**
* 网页扫码类型,默认支持二维码和条码
*/
webScanType?: ('qrCode' | 'barCode')[],
/**
* 网页扫码canvas是否启用默认启用
*/
webCanvasEnabled?: boolean,
/**
* 网页扫码成功提示音地址,默认使用内置提示音
*/
webScanBeepAudio?: string,
/**
* 网页扫码成功提示音是否启用,默认启用
*/
webScanBeepEnabled?: boolean,
/** /**
* 微信JSSDK配置微信环境才会生效配置后会自动初始化微信JSSDK * 微信JSSDK配置微信环境才会生效配置后会自动初始化微信JSSDK
*/ */
@@ -14,6 +30,31 @@ interface ScanConfigOptions {
* 微信JSSDK配置API地址调用接口会带上当前页面url作为参数 * 微信JSSDK配置API地址调用接口会带上当前页面url作为参数
*/ */
apiUrl: string, apiUrl: string,
/**
* 微信JSSDK配置参数不配置则自动获取
*/
sdkConfig?: {
/**
* 是否开启调试模式
*/
debug?: boolean,
/**
* 微信公众平台应用ID
*/
appId: string,
/**
* 时间戳
*/
timestamp: number,
/**
* 随机字符串
*/
nonceStr: string,
/**
* 签名
*/
signature: string,
},
/** /**
* 微信JSSDK配置SDK地址默认为https://res.wx.qq.com/open/js/jweixin-1.6.0.js * 微信JSSDK配置SDK地址默认为https://res.wx.qq.com/open/js/jweixin-1.6.0.js
*/ */

6
dist/index.html vendored
View File

@@ -100,7 +100,11 @@
output("call ready"); output("call ready");
hide(); hide();
var url = "https://vet.iqudoo.com/api?action=api.biz.wechat.JSSDKConfig"; var url = "https://vet.iqudoo.com/api?action=api.biz.wechat.JSSDKConfig";
initSDK({ initWechatJssdk: { apiUrl: url } }, function () { initSDK({
webCanvasEnabled: true,
webScanBeepEnabled: true,
initWechatJssdk: { apiUrl: url }
}, function () {
IScan.setStatusListener(function (res) { IScan.setStatusListener(function (res) {
output("status", IScan.getStatus()); output("status", IScan.getStatus());
}); });

2
dist/index.js vendored

File diff suppressed because one or more lines are too long

BIN
res/scan_beep.ogg Normal file

Binary file not shown.

View File

@@ -13,11 +13,13 @@ export function getVersion() {
} }
export function getConfig(key) { export function getConfig(key) {
let item = _customConfig[key]; if (Object.prototype.hasOwnProperty.call(_customConfig, key)) {
if (!item) { return _customConfig[key];
item = _defConfig[key];
} }
return item; if (Object.prototype.hasOwnProperty.call(_defConfig, key)) {
return _defConfig[key];
}
return undefined;
} }
export function setConfig(config) { export function setConfig(config) {

View File

@@ -1,11 +1,14 @@
import { createUUID } from "../../utils/uuid"; import { createUUID } from "../../utils/uuid";
import { getConfig } from "../config"; import { getConfig } from "../config";
import scanBeepAudio from "../../../res/scan_beep.ogg";
const scanWeb = { const scanWeb = {
uuid: null, uuid: null,
finish: true finish: true
} }
const DEFAULT_SCAN_BEEP_AUDIO = scanBeepAudio;
function removeEl(id) { function removeEl(id) {
try { try {
let el = document.getElementById(id); let el = document.getElementById(id);
@@ -101,6 +104,24 @@ function drawBarcode(context, width, barcode) {
} }
} }
function playScanBeep() {
if (getConfig("webScanBeepEnabled") === false) {
return;
}
const audioSrc = getConfig("webScanBeepAudio") || DEFAULT_SCAN_BEEP_AUDIO;
if (!audioSrc || typeof Audio === 'undefined') {
return;
}
try {
const audio = new Audio(audioSrc);
const playPromise = audio.play();
playPromise && playPromise.catch && playPromise.catch(() => {
// no thing
});
} catch (e) {
}
}
export function isSupportWebScan() { export function isSupportWebScan() {
return typeof navigator !== 'undefined' return typeof navigator !== 'undefined'
&& navigator.mediaDevices && navigator.mediaDevices
@@ -184,7 +205,7 @@ function detectImageFile(detector, file) {
} }
export function startScanForImage() { export function startScanForImage() {
return createBarcodeDetector(getConfig("scanType")).then(detector => { return createBarcodeDetector(getConfig("webScanType")).then(detector => {
return chooseImageFile().then(file => detectImageFile(detector, file)); return chooseImageFile().then(file => detectImageFile(detector, file));
}).then(code => { }).then(code => {
if (code && code.rawValue) { if (code && code.rawValue) {
@@ -207,6 +228,7 @@ export function startScanForWeb(canvasStyle, onResult) {
let videoEl = createEl("video", let videoEl = createEl("video",
"__webscan_video__", "__webscan_video__",
"display: none", false); "display: none", false);
let canvasEnabled = getConfig("webCanvasEnabled") !== false;
let canvasDisplay = ""; let canvasDisplay = "";
let canvasBaseStyle = canvasStyle || "position: fixed; width: 300px; height: 240px; top: 0; left: 0; z-index: 9999;"; let canvasBaseStyle = canvasStyle || "position: fixed; width: 300px; height: 240px; top: 0; left: 0; z-index: 9999;";
let canvasEl = createEl("canvas", let canvasEl = createEl("canvas",
@@ -221,7 +243,7 @@ export function startScanForWeb(canvasStyle, onResult) {
videoEl.width = 300; videoEl.width = 300;
videoEl.height = 300; videoEl.height = 300;
videoEl.uuid = scanWeb.uuid; videoEl.uuid = scanWeb.uuid;
createBarcodeDetector(getConfig("scanType")).then(detector => { createBarcodeDetector(getConfig("webScanType")).then(detector => {
return navigator.mediaDevices.getUserMedia({ return navigator.mediaDevices.getUserMedia({
video: { video: {
facingMode: "environment" facingMode: "environment"
@@ -238,15 +260,6 @@ export function startScanForWeb(canvasStyle, onResult) {
videoEl.srcObject = stream; videoEl.srcObject = stream;
videoEl.setAttribute("playsinline", true); // iOS使用 videoEl.setAttribute("playsinline", true); // iOS使用
videoEl.play(); videoEl.play();
let closeWebScan = getConfig("closeWebScan", () => {
// no thing
});
let displayWebScan = getConfig("displayWebScan", (canvasEl, cancal) => {
// no thing
});
displayWebScan && displayWebScan(canvasEl, () => {
stopScanForWeb();
});
canvasEl.style.display = "none"; canvasEl.style.display = "none";
let detecting = false; let detecting = false;
let displayed = false; let displayed = false;
@@ -259,7 +272,6 @@ export function startScanForWeb(canvasStyle, onResult) {
try { try {
stream.getTracks()[0].stop(); stream.getTracks()[0].stop();
} catch (_e) { } } catch (_e) { }
closeWebScan && closeWebScan();
}; };
let tick = () => { let tick = () => {
try { try {
@@ -269,7 +281,7 @@ export function startScanForWeb(canvasStyle, onResult) {
context.setTransform(-1, 0, 0, 1, canvasEl.width, 0); context.setTransform(-1, 0, 0, 1, canvasEl.width, 0);
context.drawImage(videoEl, 0, 0, canvasEl.width, canvasEl.height); context.drawImage(videoEl, 0, 0, canvasEl.width, canvasEl.height);
context.setTransform(1, 0, 0, 1, 0, 0); context.setTransform(1, 0, 0, 1, 0, 0);
if (!displayed) { if (canvasEnabled && !displayed) {
displayed = true; displayed = true;
canvasEl.style.display = canvasDisplay || ""; canvasEl.style.display = canvasDisplay || "";
} }
@@ -277,10 +289,11 @@ export function startScanForWeb(canvasStyle, onResult) {
detector.detect(videoEl).then(barcodes => { detector.detect(videoEl).then(barcodes => {
const code = barcodes && barcodes[0]; const code = barcodes && barcodes[0];
if (code && code.rawValue && scanWeb.uuid == currentUuid) { if (code && code.rawValue && scanWeb.uuid == currentUuid) {
if (onResult && !onResult(code.rawValue)) { if (!onResult || !onResult(code.rawValue)) {
return; return;
} }
drawBarcode(context, canvasEl.width, code); drawBarcode(context, canvasEl.width, code);
playScanBeep();
scanWeb.uuid = null; scanWeb.uuid = null;
scanWeb.finish = true; scanWeb.finish = true;
close(); close();

View File

@@ -45,9 +45,12 @@ function loadWxScript() {
function fetchWxConfig() { function fetchWxConfig() {
let initWechatJssdk = toAny(getConfig("initWechatJssdk"), {}); let initWechatJssdk = toAny(getConfig("initWechatJssdk"), {});
if (!!initWechatJssdk.sdkConfig) {
return Promise.resolve(toAny(initWechatJssdk.sdkConfig, {}));
}
let apiUrl = toAny(initWechatJssdk.apiUrl, ""); let apiUrl = toAny(initWechatJssdk.apiUrl, "");
if (!apiUrl) { if (!apiUrl) {
return Promise.reject(new Error("initWechatJssdk.apiUrl is required, but not found")); return Promise.reject(new Error("initWechatJssdk.apiUrl or initWechatJssdk.sdkConfig is required, but not found"));
} }
return request({ return request({
url: apiUrl, url: apiUrl,
@@ -61,7 +64,7 @@ function fetchWxConfig() {
return null; return null;
} }
if (data.code !== 0) { if (data.code !== 0) {
throw new Error(data.msg || "wx config fetch failed"); throw new Error(data.msg || "wechat jssdk config fetch failed");
} }
if (data.data) { if (data.data) {
return data.data; return data.data;
@@ -94,10 +97,10 @@ export function initWxJssdk() {
const wx = items[0]; const wx = items[0];
const config = items[1]; const config = items[1];
if (!wx || !wx.config) { if (!wx || !wx.config) {
throw new Error("wx jssdk is not ready"); throw new Error("wechat jssdk is not ready");
} }
if (!config) { if (!config) {
throw new Error("wx config is empty"); throw new Error("wechat jssdk config is empty");
} }
const jsApiList = config.jsApiList || []; const jsApiList = config.jsApiList || [];
if (jsApiList.indexOf(WX_SCAN_API) === -1) { if (jsApiList.indexOf(WX_SCAN_API) === -1) {

41
types/index.d.ts vendored
View File

@@ -6,6 +6,22 @@ interface ScanConfigOptions {
* 网页扫码canvas样式 * 网页扫码canvas样式
*/ */
webCanvasStyle?: string, webCanvasStyle?: string,
/**
* 网页扫码类型,默认支持二维码和条码
*/
webScanType?: ('qrCode' | 'barCode')[],
/**
* 网页扫码canvas是否启用默认启用
*/
webCanvasEnabled?: boolean,
/**
* 网页扫码成功提示音地址,默认使用内置提示音
*/
webScanBeepAudio?: string,
/**
* 网页扫码成功提示音是否启用,默认启用
*/
webScanBeepEnabled?: boolean,
/** /**
* 微信JSSDK配置微信环境才会生效配置后会自动初始化微信JSSDK * 微信JSSDK配置微信环境才会生效配置后会自动初始化微信JSSDK
*/ */
@@ -14,6 +30,31 @@ interface ScanConfigOptions {
* 微信JSSDK配置API地址调用接口会带上当前页面url作为参数 * 微信JSSDK配置API地址调用接口会带上当前页面url作为参数
*/ */
apiUrl: string, apiUrl: string,
/**
* 微信JSSDK配置参数不配置则自动获取
*/
sdkConfig?: {
/**
* 是否开启调试模式
*/
debug?: boolean,
/**
* 微信公众平台应用ID
*/
appId: string,
/**
* 时间戳
*/
timestamp: number,
/**
* 随机字符串
*/
nonceStr: string,
/**
* 签名
*/
signature: string,
},
/** /**
* 微信JSSDK配置SDK地址默认为https://res.wx.qq.com/open/js/jweixin-1.6.0.js * 微信JSSDK配置SDK地址默认为https://res.wx.qq.com/open/js/jweixin-1.6.0.js
*/ */

View File

@@ -28,7 +28,7 @@ const config = {
template: 'demo.html' template: 'demo.html'
}), }),
new CpWebpackPlugin([ new CpWebpackPlugin([
{ from: path.resolve('./types'), to: path.resolve('./dist') } { from: path.resolve('./types'), to: path.resolve('./dist') },
]) ])
], ],
devtool: 'cheap-module-souce-map', devtool: 'cheap-module-souce-map',

View File

@@ -23,6 +23,14 @@ const rules = [{
limit: 8192, limit: 8192,
}, },
}], }],
}, {
test: /\.(ogg|mp3|wav)$/,
use: [{
loader: 'url-loader',
options: {
limit: 65536,
},
}],
}, { }, {
test: /\.css$/, test: /\.css$/,
use: [{ use: [{