@pisell/materials 6.0.17 → 6.0.19

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.
Files changed (41) hide show
  1. package/build/lowcode/assets-daily.json +11 -11
  2. package/build/lowcode/assets-dev.json +2 -2
  3. package/build/lowcode/assets-prod.json +11 -11
  4. package/build/lowcode/index.js +1 -1
  5. package/build/lowcode/meta.js +6 -6
  6. package/build/lowcode/preview.js +7 -7
  7. package/build/lowcode/render/default/view.css +1 -1
  8. package/build/lowcode/render/default/view.js +21 -21
  9. package/build/lowcode/view.css +1 -1
  10. package/build/lowcode/view.js +21 -21
  11. package/es/components/dataSourceComponents/fields/Input/WithMode.d.ts +0 -1
  12. package/es/components/dataSourceComponents/fields/Input/WithMode.js +48 -508
  13. package/es/components/pisellQRScanner/index.d.ts +37 -0
  14. package/es/components/pisellQRScanner/index.js +1153 -0
  15. package/es/components/pisellQRScanner/index.less +71 -0
  16. package/es/index.d.ts +2 -0
  17. package/es/index.js +1 -0
  18. package/es/locales/en-US.d.ts +13 -0
  19. package/es/locales/en-US.js +14 -3
  20. package/es/locales/zh-CN.d.ts +9 -0
  21. package/es/locales/zh-CN.js +11 -1
  22. package/es/locales/zh-TW.d.ts +9 -0
  23. package/es/locales/zh-TW.js +11 -1
  24. package/lib/components/dataSourceComponents/fields/Input/WithMode.d.ts +0 -1
  25. package/lib/components/dataSourceComponents/fields/Input/WithMode.js +44 -323
  26. package/lib/components/pisellQRScanner/index.d.ts +37 -0
  27. package/lib/components/pisellQRScanner/index.js +706 -0
  28. package/lib/components/pisellQRScanner/index.less +71 -0
  29. package/lib/index.d.ts +2 -0
  30. package/lib/index.js +3 -0
  31. package/lib/locales/en-US.d.ts +13 -0
  32. package/lib/locales/en-US.js +19 -1
  33. package/lib/locales/zh-CN.d.ts +9 -0
  34. package/lib/locales/zh-CN.js +11 -1
  35. package/lib/locales/zh-TW.d.ts +9 -0
  36. package/lib/locales/zh-TW.js +11 -1
  37. package/lowcode/pisell-qrscanner/meta.ts +86 -0
  38. package/lowcode/pisell-qrscanner/snippets.ts +25 -0
  39. package/package.json +3 -3
  40. package/es/components/dataSourceComponents/fields/Input/WithMode.less +0 -96
  41. package/lib/components/dataSourceComponents/fields/Input/WithMode.less +0 -96
@@ -0,0 +1,706 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/components/pisellQRScanner/index.tsx
30
+ var pisellQRScanner_exports = {};
31
+ __export(pisellQRScanner_exports, {
32
+ default: () => pisellQRScanner_default
33
+ });
34
+ module.exports = __toCommonJS(pisellQRScanner_exports);
35
+ var import_react = __toESM(require("react"));
36
+ var import_antd = require("antd");
37
+ var import_library = require("@zxing/library");
38
+ var import_iconfont = __toESM(require("../iconfont"));
39
+ var import_index = require("./index.less");
40
+ var import_react_dom = require("react-dom");
41
+ var import_locales = require("../../locales");
42
+ var isQRCode = (format) => {
43
+ return format === import_library.BarcodeFormat.QR_CODE;
44
+ };
45
+ var PisellQRScanner = ({
46
+ visible,
47
+ onClose,
48
+ onScan,
49
+ showUpload = true,
50
+ // 默认显示上传图片按钮
51
+ // 明确解构其他可能的属性,避免通过扩展运算符传递不必要的属性到DOM
52
+ style,
53
+ className,
54
+ ...otherProps
55
+ // 捕获其他可能的属性,但不使用它们
56
+ }) => {
57
+ const videoRef = (0, import_react.useRef)(null);
58
+ const fileInputRef = (0, import_react.useRef)(null);
59
+ const codeReaderRef = (0, import_react.useRef)(null);
60
+ const handleScanClose = () => {
61
+ console.log("关闭扫码界面,释放摄像头资源");
62
+ onClose();
63
+ try {
64
+ if (codeReaderRef.current) {
65
+ console.log("重置codeReader...");
66
+ codeReaderRef.current.reset();
67
+ }
68
+ } catch (err) {
69
+ console.error("重置codeReader出错:", err);
70
+ }
71
+ try {
72
+ if (videoRef.current && videoRef.current.srcObject) {
73
+ console.log("停止视频流...");
74
+ const stream = videoRef.current.srcObject;
75
+ stream.getTracks().forEach((track) => {
76
+ console.log(`停止${track.kind}轨道`);
77
+ track.stop();
78
+ });
79
+ videoRef.current.srcObject = null;
80
+ }
81
+ } catch (err) {
82
+ console.error("停止视频流出错:", err);
83
+ }
84
+ };
85
+ const handleUploadClick = () => {
86
+ var _a;
87
+ (_a = fileInputRef.current) == null ? void 0 : _a.click();
88
+ };
89
+ const handleFileChange = async (event) => {
90
+ const files = event.target.files;
91
+ if (!files || files.length === 0)
92
+ return;
93
+ try {
94
+ const file = files[0];
95
+ if (!file.type.startsWith("image/")) {
96
+ import_antd.message.error((0, import_locales.getText)("qrscanner-error-upload-image"));
97
+ return;
98
+ }
99
+ try {
100
+ const reader = new FileReader();
101
+ reader.onload = async (e) => {
102
+ if (!e.target || !e.target.result) {
103
+ import_antd.message.error({ content: (0, import_locales.getText)("qrscanner-error-load-failed"), key: "qrProcessing" });
104
+ return;
105
+ }
106
+ const img = new Image();
107
+ img.onload = async () => {
108
+ try {
109
+ console.log("图片加载完成,尺寸:", img.width, "x", img.height);
110
+ const canvas = document.createElement("canvas");
111
+ canvas.width = img.width;
112
+ canvas.height = img.height;
113
+ const ctx = canvas.getContext("2d");
114
+ if (!ctx) {
115
+ import_antd.message.error({ content: "无法创建画布上下文", key: "qrProcessing" });
116
+ return;
117
+ }
118
+ ctx.drawImage(img, 0, 0, img.width, img.height);
119
+ const methods = [
120
+ // 方法1: 原始图像
121
+ async () => {
122
+ console.log("尝试方法1: 原始图像");
123
+ const decoder = new import_library.BrowserMultiFormatReader(void 0, 2e3);
124
+ return await decoder.decodeFromImage(img);
125
+ },
126
+ // 方法2: 绿色通道增强 (针对微信二维码) - 强级别
127
+ async () => {
128
+ console.log("尝试方法2: 绿色通道强增强");
129
+ const greenCanvas = document.createElement("canvas");
130
+ greenCanvas.width = img.width;
131
+ greenCanvas.height = img.height;
132
+ const greenCtx = greenCanvas.getContext("2d");
133
+ if (!greenCtx)
134
+ throw new Error("无法创建画布上下文");
135
+ greenCtx.drawImage(img, 0, 0);
136
+ const imageData = greenCtx.getImageData(0, 0, greenCanvas.width, greenCanvas.height);
137
+ const data = imageData.data;
138
+ for (let i = 0; i < data.length; i += 4) {
139
+ const red = data[i];
140
+ const green = data[i + 1];
141
+ const blue = data[i + 2];
142
+ if (green > red * 0.85 || green > blue * 0.85) {
143
+ if (green > 100) {
144
+ data[i] = 0;
145
+ data[i + 1] = 0;
146
+ data[i + 2] = 0;
147
+ } else {
148
+ data[i] = 255;
149
+ data[i + 1] = 255;
150
+ data[i + 2] = 255;
151
+ }
152
+ }
153
+ }
154
+ greenCtx.putImageData(imageData, 0, 0);
155
+ const greenImg = new Image();
156
+ return new Promise((resolve, reject) => {
157
+ greenImg.onload = async () => {
158
+ try {
159
+ const decoder = new import_library.BrowserMultiFormatReader(void 0, 2e3);
160
+ const result2 = await decoder.decodeFromImage(greenImg);
161
+ resolve(result2);
162
+ } catch (err) {
163
+ reject(err);
164
+ }
165
+ };
166
+ greenImg.onerror = reject;
167
+ greenImg.src = greenCanvas.toDataURL("image/png");
168
+ });
169
+ },
170
+ // 特殊处理:微信绿码专用增强(降低绿色阈值)
171
+ async () => {
172
+ console.log("尝试微信绿码专用优化方法");
173
+ const wechatCanvas = document.createElement("canvas");
174
+ wechatCanvas.width = img.width;
175
+ wechatCanvas.height = img.height;
176
+ const wechatCtx = wechatCanvas.getContext("2d");
177
+ if (!wechatCtx)
178
+ throw new Error("无法创建画布上下文");
179
+ wechatCtx.drawImage(img, 0, 0);
180
+ const imageData = wechatCtx.getImageData(0, 0, wechatCanvas.width, wechatCanvas.height);
181
+ const data = imageData.data;
182
+ for (let i = 0; i < data.length; i += 4) {
183
+ const red = data[i];
184
+ const green = data[i + 1];
185
+ const blue = data[i + 2];
186
+ const brightness = (red + green + blue) / 3;
187
+ const greenRatio = green / (red + green + blue + 1);
188
+ if (greenRatio > 0.35 && green > 80 && brightness < 200) {
189
+ data[i] = 0;
190
+ data[i + 1] = 0;
191
+ data[i + 2] = 0;
192
+ } else {
193
+ data[i] = 255;
194
+ data[i + 1] = 255;
195
+ data[i + 2] = 255;
196
+ }
197
+ }
198
+ wechatCtx.putImageData(imageData, 0, 0);
199
+ const wechatImg = new Image();
200
+ return new Promise((resolve, reject) => {
201
+ wechatImg.onload = async () => {
202
+ try {
203
+ const decoder = new import_library.BrowserMultiFormatReader(void 0, 2500);
204
+ const result2 = await decoder.decodeFromImage(wechatImg);
205
+ resolve(result2);
206
+ } catch (err) {
207
+ reject(err);
208
+ }
209
+ };
210
+ wechatImg.onerror = reject;
211
+ wechatImg.src = wechatCanvas.toDataURL("image/png");
212
+ });
213
+ },
214
+ // 方法3: 仅绿色通道
215
+ async () => {
216
+ console.log("尝试方法3: 仅使用绿色通道");
217
+ const greenOnlyCanvas = document.createElement("canvas");
218
+ greenOnlyCanvas.width = img.width;
219
+ greenOnlyCanvas.height = img.height;
220
+ const greenOnlyCtx = greenOnlyCanvas.getContext("2d");
221
+ if (!greenOnlyCtx)
222
+ throw new Error("无法创建画布上下文");
223
+ greenOnlyCtx.drawImage(img, 0, 0);
224
+ const imageData = greenOnlyCtx.getImageData(0, 0, greenOnlyCanvas.width, greenOnlyCanvas.height);
225
+ const data = imageData.data;
226
+ for (let i = 0; i < data.length; i += 4) {
227
+ data[i] = 0;
228
+ data[i + 2] = 0;
229
+ }
230
+ greenOnlyCtx.putImageData(imageData, 0, 0);
231
+ const greenOnlyImg = new Image();
232
+ return new Promise((resolve, reject) => {
233
+ greenOnlyImg.onload = async () => {
234
+ try {
235
+ const decoder = new import_library.BrowserMultiFormatReader(void 0, 1500);
236
+ const result2 = await decoder.decodeFromImage(greenOnlyImg);
237
+ resolve(result2);
238
+ } catch (err) {
239
+ reject(err);
240
+ }
241
+ };
242
+ greenOnlyImg.onerror = reject;
243
+ greenOnlyImg.src = greenOnlyCanvas.toDataURL("image/png");
244
+ });
245
+ },
246
+ // 方法4: 自适应阈值二值化
247
+ async () => {
248
+ console.log("尝试方法4: 自适应阈值二值化");
249
+ const adaptiveCanvas = document.createElement("canvas");
250
+ adaptiveCanvas.width = img.width;
251
+ adaptiveCanvas.height = img.height;
252
+ const adaptiveCtx = adaptiveCanvas.getContext("2d");
253
+ if (!adaptiveCtx)
254
+ throw new Error("无法创建画布上下文");
255
+ adaptiveCtx.drawImage(img, 0, 0);
256
+ const imageData = adaptiveCtx.getImageData(0, 0, adaptiveCanvas.width, adaptiveCanvas.height);
257
+ const data = imageData.data;
258
+ let sum = 0;
259
+ let count = 0;
260
+ for (let i = 0; i < data.length; i += 4) {
261
+ const gray = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2];
262
+ sum += gray;
263
+ count++;
264
+ }
265
+ const adaptiveThreshold = sum / count * 0.85;
266
+ console.log("自适应阈值:", adaptiveThreshold);
267
+ for (let i = 0; i < data.length; i += 4) {
268
+ const gray = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2];
269
+ const val = gray < adaptiveThreshold ? 0 : 255;
270
+ data[i] = val;
271
+ data[i + 1] = val;
272
+ data[i + 2] = val;
273
+ }
274
+ adaptiveCtx.putImageData(imageData, 0, 0);
275
+ const adaptiveImg = new Image();
276
+ return new Promise((resolve, reject) => {
277
+ adaptiveImg.onload = async () => {
278
+ try {
279
+ const decoder = new import_library.BrowserMultiFormatReader(void 0, 1500);
280
+ const result2 = await decoder.decodeFromImage(adaptiveImg);
281
+ resolve(result2);
282
+ } catch (err) {
283
+ reject(err);
284
+ }
285
+ };
286
+ adaptiveImg.onerror = reject;
287
+ adaptiveImg.src = adaptiveCanvas.toDataURL("image/png");
288
+ });
289
+ },
290
+ // 方法5: 高斯模糊后锐化
291
+ async () => {
292
+ console.log("尝试方法5: 高斯模糊后锐化");
293
+ const sharpenCanvas = document.createElement("canvas");
294
+ sharpenCanvas.width = img.width;
295
+ sharpenCanvas.height = img.height;
296
+ const sharpenCtx = sharpenCanvas.getContext("2d");
297
+ if (!sharpenCtx)
298
+ throw new Error("无法创建画布上下文");
299
+ sharpenCtx.drawImage(img, 0, 0);
300
+ sharpenCtx.filter = "blur(1px)";
301
+ sharpenCtx.drawImage(img, 0, 0);
302
+ sharpenCtx.filter = "none";
303
+ const imageData = sharpenCtx.getImageData(0, 0, sharpenCanvas.width, sharpenCanvas.height);
304
+ const sharpenedData = applySharpen(imageData, sharpenCanvas.width, sharpenCanvas.height);
305
+ sharpenCtx.putImageData(sharpenedData, 0, 0);
306
+ const sharpenImg = new Image();
307
+ return new Promise((resolve, reject) => {
308
+ sharpenImg.onload = async () => {
309
+ try {
310
+ const decoder = new import_library.BrowserMultiFormatReader(void 0, 1500);
311
+ const result2 = await decoder.decodeFromImage(sharpenImg);
312
+ resolve(result2);
313
+ } catch (err) {
314
+ reject(err);
315
+ }
316
+ };
317
+ sharpenImg.onerror = reject;
318
+ sharpenImg.src = sharpenCanvas.toDataURL("image/png");
319
+ });
320
+ },
321
+ // 方法6: 反色处理
322
+ async () => {
323
+ console.log("尝试方法6: 反色处理");
324
+ const invertCanvas = document.createElement("canvas");
325
+ invertCanvas.width = img.width;
326
+ invertCanvas.height = img.height;
327
+ const invertCtx = invertCanvas.getContext("2d");
328
+ if (!invertCtx)
329
+ throw new Error("无法创建画布上下文");
330
+ invertCtx.drawImage(img, 0, 0);
331
+ const imageData = invertCtx.getImageData(0, 0, invertCanvas.width, invertCanvas.height);
332
+ const data = imageData.data;
333
+ for (let i = 0; i < data.length; i += 4) {
334
+ data[i] = 255 - data[i];
335
+ data[i + 1] = 255 - data[i + 1];
336
+ data[i + 2] = 255 - data[i + 2];
337
+ }
338
+ invertCtx.putImageData(imageData, 0, 0);
339
+ const invertImg = new Image();
340
+ return new Promise((resolve, reject) => {
341
+ invertImg.onload = async () => {
342
+ try {
343
+ const decoder = new import_library.BrowserMultiFormatReader(void 0, 1500);
344
+ const result2 = await decoder.decodeFromImage(invertImg);
345
+ resolve(result2);
346
+ } catch (err) {
347
+ reject(err);
348
+ }
349
+ };
350
+ invertImg.onerror = reject;
351
+ invertImg.src = invertCanvas.toDataURL("image/png");
352
+ });
353
+ },
354
+ // 方法7: HSV色彩空间处理微信绿色
355
+ async () => {
356
+ console.log("尝试方法7: HSV色彩空间处理");
357
+ const hsvCanvas = document.createElement("canvas");
358
+ hsvCanvas.width = img.width;
359
+ hsvCanvas.height = img.height;
360
+ const hsvCtx = hsvCanvas.getContext("2d");
361
+ if (!hsvCtx)
362
+ throw new Error("无法创建画布上下文");
363
+ hsvCtx.drawImage(img, 0, 0);
364
+ const imageData = hsvCtx.getImageData(0, 0, hsvCanvas.width, hsvCanvas.height);
365
+ const data = imageData.data;
366
+ for (let i = 0; i < data.length; i += 4) {
367
+ const r = data[i] / 255;
368
+ const g = data[i + 1] / 255;
369
+ const b = data[i + 2] / 255;
370
+ const max = Math.max(r, g, b);
371
+ const min = Math.min(r, g, b);
372
+ const diff = max - min;
373
+ let h = 0;
374
+ if (max === min) {
375
+ h = 0;
376
+ } else if (max === r) {
377
+ h = (60 * ((g - b) / diff) + 360) % 360;
378
+ } else if (max === g) {
379
+ h = 60 * ((b - r) / diff) + 120;
380
+ } else {
381
+ h = 60 * ((r - g) / diff) + 240;
382
+ }
383
+ const s = max === 0 ? 0 : diff / max;
384
+ const v = max;
385
+ const isGreen = h >= 90 && h <= 150;
386
+ if (isGreen && s > 0.2) {
387
+ data[i] = 0;
388
+ data[i + 1] = 0;
389
+ data[i + 2] = 0;
390
+ } else {
391
+ data[i] = 255;
392
+ data[i + 1] = 255;
393
+ data[i + 2] = 255;
394
+ }
395
+ }
396
+ hsvCtx.putImageData(imageData, 0, 0);
397
+ const hsvImg = new Image();
398
+ return new Promise((resolve, reject) => {
399
+ hsvImg.onload = async () => {
400
+ try {
401
+ const decoder = new import_library.BrowserMultiFormatReader(void 0, 1500);
402
+ const result2 = await decoder.decodeFromImage(hsvImg);
403
+ resolve(result2);
404
+ } catch (err) {
405
+ reject(err);
406
+ }
407
+ };
408
+ hsvImg.onerror = reject;
409
+ hsvImg.src = hsvCanvas.toDataURL("image/png");
410
+ });
411
+ }
412
+ ];
413
+ let success = false;
414
+ let result = null;
415
+ try {
416
+ for (let i = 0; i < methods.length; i++) {
417
+ try {
418
+ console.log(`尝试方法${i + 1}...`);
419
+ result = await methods[i]();
420
+ if (result) {
421
+ success = true;
422
+ console.log(`方法${i + 1}成功!`);
423
+ break;
424
+ }
425
+ } catch (err) {
426
+ console.error(`方法${i + 1}失败:`, err);
427
+ }
428
+ }
429
+ if (success && result) {
430
+ const text = result.getText();
431
+ const format = result.getBarcodeFormat();
432
+ const isQR = isQRCode(format);
433
+ console.log(`识别成功 - 类型: ${isQR ? "二维码" : "条形码"}, 内容:`, text);
434
+ import_antd.message.destroy("qrProcessing");
435
+ onScan(text);
436
+ handleScanClose();
437
+ } else {
438
+ console.log("识别失败,所有方法都尝试过了");
439
+ import_antd.message.destroy("qrProcessing");
440
+ handleScanClose();
441
+ setTimeout(() => {
442
+ import_antd.message.error({
443
+ content: (0, import_locales.getText)("qrscanner-error-no-code"),
444
+ duration: 3
445
+ });
446
+ }, 100);
447
+ }
448
+ } catch (outerError) {
449
+ console.error("识别过程发生意外错误:", outerError);
450
+ import_antd.message.destroy("qrProcessing");
451
+ handleScanClose();
452
+ setTimeout(() => {
453
+ import_antd.message.error({
454
+ content: (0, import_locales.getText)("qrscanner-error-no-code"),
455
+ duration: 3
456
+ });
457
+ }, 100);
458
+ }
459
+ } catch (processError) {
460
+ console.error("图像处理错误:", processError);
461
+ import_antd.message.destroy("qrProcessing");
462
+ handleScanClose();
463
+ setTimeout(() => {
464
+ import_antd.message.error({
465
+ content: (0, import_locales.getText)("qrscanner-error-process-image"),
466
+ duration: 3
467
+ });
468
+ }, 100);
469
+ }
470
+ };
471
+ img.onerror = () => {
472
+ import_antd.message.destroy("qrProcessing");
473
+ handleScanClose();
474
+ import_antd.message.error((0, import_locales.getText)("qrscanner-error-load-failed"));
475
+ };
476
+ img.src = e.target.result.toString();
477
+ };
478
+ reader.onerror = () => {
479
+ import_antd.message.destroy("qrProcessing");
480
+ handleScanClose();
481
+ import_antd.message.error((0, import_locales.getText)("qrscanner-error-load-failed"));
482
+ };
483
+ reader.readAsDataURL(file);
484
+ } catch (error) {
485
+ console.error("识别过程错误:", error);
486
+ import_antd.message.destroy("qrProcessing");
487
+ handleScanClose();
488
+ import_antd.message.error((0, import_locales.getText)("qrscanner-error-process-image"));
489
+ }
490
+ } catch (error) {
491
+ console.error("处理图片出错", error);
492
+ import_antd.message.destroy("qrProcessing");
493
+ handleScanClose();
494
+ import_antd.message.error((0, import_locales.getText)("qrscanner-error-process-image"));
495
+ } finally {
496
+ if (fileInputRef.current) {
497
+ fileInputRef.current.value = "";
498
+ }
499
+ }
500
+ };
501
+ const applySharpen = (imageData, width, height) => {
502
+ const data = imageData.data;
503
+ const temp = new Uint8ClampedArray(data);
504
+ const kernel = [
505
+ 0,
506
+ -1,
507
+ 0,
508
+ -1,
509
+ 5,
510
+ -1,
511
+ 0,
512
+ -1,
513
+ 0
514
+ ];
515
+ for (let y = 1; y < height - 1; y++) {
516
+ for (let x = 1; x < width - 1; x++) {
517
+ const idx = (y * width + x) * 4;
518
+ for (let c = 0; c < 3; c++) {
519
+ let val = 0;
520
+ for (let ky = -1; ky <= 1; ky++) {
521
+ for (let kx = -1; kx <= 1; kx++) {
522
+ const kidx = ((y + ky) * width + (x + kx)) * 4 + c;
523
+ val += temp[kidx] * kernel[(ky + 1) * 3 + (kx + 1)];
524
+ }
525
+ }
526
+ data[idx + c] = Math.min(255, Math.max(0, val));
527
+ }
528
+ }
529
+ }
530
+ return imageData;
531
+ };
532
+ (0, import_react.useEffect)(() => {
533
+ if (visible) {
534
+ const initCamera = async () => {
535
+ try {
536
+ if (codeReaderRef.current) {
537
+ try {
538
+ codeReaderRef.current.reset();
539
+ } catch (err) {
540
+ console.log("重置之前的实例出错", err);
541
+ }
542
+ }
543
+ codeReaderRef.current = new import_library.BrowserMultiFormatReader(void 0, 300);
544
+ console.log("创建二维码阅读器实例成功");
545
+ codeReaderRef.current.decodeFromVideoDevice(
546
+ null,
547
+ // 使用默认设备
548
+ videoRef.current,
549
+ (result, err) => {
550
+ if (result) {
551
+ const text = result.getText();
552
+ const format = result.getBarcodeFormat();
553
+ const isQR = isQRCode(format);
554
+ console.log(`扫描成功 - 类型: ${isQR ? "二维码" : "条形码"}, 内容:`, text);
555
+ onScan(text);
556
+ handleScanClose();
557
+ }
558
+ if (err && !(err instanceof import_library.NotFoundException)) {
559
+ console.error("扫描过程中出错:", err);
560
+ }
561
+ }
562
+ );
563
+ } catch (err) {
564
+ console.error("摄像头初始化错误", err);
565
+ handleScanClose();
566
+ setTimeout(() => {
567
+ import_antd.message.error({
568
+ content: (0, import_locales.getText)("qrscanner-error-camera-init"),
569
+ duration: 3
570
+ });
571
+ }, 100);
572
+ }
573
+ };
574
+ initCamera();
575
+ }
576
+ }, [visible]);
577
+ (0, import_react.useEffect)(() => {
578
+ return () => {
579
+ if (codeReaderRef.current) {
580
+ try {
581
+ codeReaderRef.current.reset();
582
+ } catch (err) {
583
+ console.error("清理资源时出错", err);
584
+ }
585
+ }
586
+ };
587
+ }, []);
588
+ if (!visible)
589
+ return null;
590
+ return (0, import_react_dom.createPortal)(
591
+ /* @__PURE__ */ import_react.default.createElement(
592
+ "div",
593
+ {
594
+ className: "pisell-qr-scanner-fullscreen",
595
+ style: {
596
+ zIndex: 99999,
597
+ position: "fixed",
598
+ top: 0,
599
+ left: 0,
600
+ right: 0,
601
+ bottom: 0,
602
+ width: "100vw",
603
+ height: "100vh",
604
+ backgroundColor: "#000",
605
+ margin: 0,
606
+ padding: 0,
607
+ overflow: "hidden",
608
+ display: "flex",
609
+ justifyContent: "center",
610
+ alignItems: "center",
611
+ boxSizing: "border-box",
612
+ // 合并自定义样式,但不传递其他可能的属性
613
+ ...style
614
+ }
615
+ },
616
+ /* @__PURE__ */ import_react.default.createElement(
617
+ "div",
618
+ {
619
+ className: "scan-container",
620
+ style: {
621
+ position: "relative",
622
+ width: "100%",
623
+ height: "100%",
624
+ overflow: "hidden"
625
+ }
626
+ },
627
+ /* @__PURE__ */ import_react.default.createElement(
628
+ "video",
629
+ {
630
+ ref: videoRef,
631
+ className: "scan-video",
632
+ style: {
633
+ width: "100%",
634
+ height: "100%",
635
+ objectFit: "cover"
636
+ },
637
+ autoPlay: true,
638
+ playsInline: true,
639
+ muted: true
640
+ }
641
+ )
642
+ ),
643
+ /* @__PURE__ */ import_react.default.createElement(
644
+ import_iconfont.default,
645
+ {
646
+ type: "pisell2-arrow-left",
647
+ className: "scan-close-left",
648
+ style: {
649
+ zIndex: 1e5,
650
+ position: "fixed",
651
+ top: "20px",
652
+ left: "20px",
653
+ fontSize: "24px",
654
+ color: "#fff",
655
+ backgroundColor: "rgba(255, 255, 255, 0.15)",
656
+ width: "44px",
657
+ height: "44px",
658
+ display: "flex",
659
+ alignItems: "center",
660
+ justifyContent: "center",
661
+ borderRadius: "50%",
662
+ cursor: "pointer"
663
+ },
664
+ onClick: handleScanClose
665
+ }
666
+ ),
667
+ showUpload && /* @__PURE__ */ import_react.default.createElement(
668
+ import_iconfont.default,
669
+ {
670
+ type: "pisell2-image-01",
671
+ className: "scan-upload",
672
+ style: {
673
+ zIndex: 1e5,
674
+ position: "fixed",
675
+ right: "30px",
676
+ bottom: "60px",
677
+ fontSize: "48px",
678
+ color: "#fff",
679
+ backgroundColor: "rgba(255, 255, 255, 0.15)",
680
+ width: "88px",
681
+ height: "88px",
682
+ display: "flex",
683
+ alignItems: "center",
684
+ justifyContent: "center",
685
+ borderRadius: "50%",
686
+ cursor: "pointer"
687
+ },
688
+ onClick: handleUploadClick
689
+ }
690
+ ),
691
+ /* @__PURE__ */ import_react.default.createElement(
692
+ "input",
693
+ {
694
+ type: "file",
695
+ ref: fileInputRef,
696
+ onChange: handleFileChange,
697
+ accept: "image/*",
698
+ className: "scan-file-input",
699
+ style: { display: "none" }
700
+ }
701
+ )
702
+ ),
703
+ document.body
704
+ );
705
+ };
706
+ var pisellQRScanner_default = PisellQRScanner;