customer-chat-sdk 1.1.1 → 1.1.2
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/dist/core/CustomerSDK.d.ts +1 -0
- package/dist/core/CustomerSDK.d.ts.map +1 -1
- package/dist/core/IconManager.d.ts +6 -1
- package/dist/core/IconManager.d.ts.map +1 -1
- package/dist/core/ScreenshotManager.d.ts +1 -1
- package/dist/core/ScreenshotManager.d.ts.map +1 -1
- package/dist/customer-sdk.cjs.js +181 -116
- package/dist/customer-sdk.esm.js +181 -116
- package/dist/customer-sdk.min.js +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/customer-sdk.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// 直接使用base64字符串,避免打包后路径问题
|
|
2
2
|
const iconImage = 'data:image/png;base64,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';
|
|
3
3
|
class IconManager {
|
|
4
|
-
constructor(position, debug = false) {
|
|
4
|
+
constructor(position, debug = false, target) {
|
|
5
5
|
this.iconElement = null;
|
|
6
6
|
this.badgeElement = null;
|
|
7
7
|
this.onClickCallback = null;
|
|
@@ -19,8 +19,11 @@ class IconManager {
|
|
|
19
19
|
this.iconPosition = null; // 图标位置配置
|
|
20
20
|
this.debug = false; // debug 模式标志
|
|
21
21
|
this.isClickEnabled = true; // 是否允许点击(iframe 打开时禁用)
|
|
22
|
+
this.target = null; // 图标传送目标元素(可以是 HTMLElement 或选择器字符串)
|
|
22
23
|
this.iconPosition = position || null;
|
|
23
24
|
this.debug = debug;
|
|
25
|
+
// 保存 target(可以是 HTMLElement 或字符串选择器)
|
|
26
|
+
this.target = target || null;
|
|
24
27
|
}
|
|
25
28
|
/**
|
|
26
29
|
* 显示悬浮图标
|
|
@@ -119,8 +122,18 @@ class IconManager {
|
|
|
119
122
|
this.iconElement.appendChild(imgContainer);
|
|
120
123
|
// 添加拖动和点击事件
|
|
121
124
|
this.setupDragEvents();
|
|
122
|
-
//
|
|
123
|
-
|
|
125
|
+
// 添加到目标元素(如果 target 是字符串,需要重新查找,因为可能在初始化时元素还不存在)
|
|
126
|
+
const targetElement = this.getTargetElement();
|
|
127
|
+
if (targetElement) {
|
|
128
|
+
targetElement.appendChild(this.iconElement);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
// 如果目标元素不存在,回退到 document.body
|
|
132
|
+
document.body.appendChild(this.iconElement);
|
|
133
|
+
if (this.debug) {
|
|
134
|
+
console.warn('Target element not found, icon added to document.body');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
124
137
|
if (this.debug) {
|
|
125
138
|
console.log('CustomerSDK icon displayed');
|
|
126
139
|
}
|
|
@@ -493,6 +506,44 @@ class IconManager {
|
|
|
493
506
|
this.iconElement.style.cursor = 'pointer';
|
|
494
507
|
}
|
|
495
508
|
}
|
|
509
|
+
/**
|
|
510
|
+
* 获取目标元素(支持动态查找)
|
|
511
|
+
*/
|
|
512
|
+
getTargetElement() {
|
|
513
|
+
if (!this.target) {
|
|
514
|
+
return document.body;
|
|
515
|
+
}
|
|
516
|
+
// 如果 target 是字符串选择器,每次都需要重新查找(支持动态元素)
|
|
517
|
+
if (typeof this.target === 'string') {
|
|
518
|
+
const element = document.querySelector(this.target);
|
|
519
|
+
if (element) {
|
|
520
|
+
return element;
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
// 如果元素不存在,回退到 document.body
|
|
524
|
+
if (this.debug) {
|
|
525
|
+
console.warn(`Target element not found: ${this.target}, falling back to document.body`);
|
|
526
|
+
}
|
|
527
|
+
return document.body;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
// 如果 target 是 HTMLElement
|
|
531
|
+
if (this.target instanceof HTMLElement) {
|
|
532
|
+
// 检查元素是否还在 DOM 中
|
|
533
|
+
if (document.body.contains(this.target)) {
|
|
534
|
+
return this.target;
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
// 如果元素不在 DOM 中,回退到 document.body
|
|
538
|
+
if (this.debug) {
|
|
539
|
+
console.warn('Target element no longer in DOM, falling back to document.body');
|
|
540
|
+
}
|
|
541
|
+
return document.body;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
// 默认回退到 document.body
|
|
545
|
+
return document.body;
|
|
546
|
+
}
|
|
496
547
|
/**
|
|
497
548
|
* 创建消息徽章(简化版)
|
|
498
549
|
*/
|
|
@@ -14540,7 +14591,7 @@ class ScreenshotManager {
|
|
|
14540
14591
|
useProxy: options.useProxy ?? true, // 默认启用代理(如果配置了proxyUrl)
|
|
14541
14592
|
engine: options.engine ?? 'modern-screenshot',
|
|
14542
14593
|
corsMode: options.corsMode ?? 'canvas-proxy',
|
|
14543
|
-
|
|
14594
|
+
debug: options.debug !== undefined ? options.debug : false, // 默认 false,不输出日志
|
|
14544
14595
|
maxRetries: options.maxRetries ?? 2,
|
|
14545
14596
|
preloadImages: options.preloadImages ?? false, // 默认不预加载,按需加载
|
|
14546
14597
|
maxConcurrentDownloads: options.maxConcurrentDownloads ?? 10, // 增加并发数
|
|
@@ -14560,9 +14611,9 @@ class ScreenshotManager {
|
|
|
14560
14611
|
this.setupMessageListener();
|
|
14561
14612
|
this.setupVisibilityChangeListener();
|
|
14562
14613
|
// 打印初始化信息
|
|
14563
|
-
if (
|
|
14614
|
+
if (this.options.debug) {
|
|
14564
14615
|
console.log('📸 ScreenshotManager 初始化完成');
|
|
14565
|
-
console.log(`📸 配置: interval=${this.options.interval}ms, engine=${this.options.engine},
|
|
14616
|
+
console.log(`📸 配置: interval=${this.options.interval}ms, engine=${this.options.engine}, debug=${this.options.debug}`);
|
|
14566
14617
|
console.log('📸 等待 iframe 发送 checkScreenshot 消息...');
|
|
14567
14618
|
}
|
|
14568
14619
|
// 启动缓存清理定时器
|
|
@@ -14585,7 +14636,7 @@ class ScreenshotManager {
|
|
|
14585
14636
|
if (this.screenshotContext) {
|
|
14586
14637
|
try {
|
|
14587
14638
|
destroyContext(this.screenshotContext);
|
|
14588
|
-
if (
|
|
14639
|
+
if (this.options.debug) {
|
|
14589
14640
|
console.log('📸 目标元素变化,清理 context');
|
|
14590
14641
|
}
|
|
14591
14642
|
}
|
|
@@ -14608,7 +14659,7 @@ class ScreenshotManager {
|
|
|
14608
14659
|
this.handleIframeMessage(event);
|
|
14609
14660
|
};
|
|
14610
14661
|
window.addEventListener('message', this.messageHandler);
|
|
14611
|
-
if (
|
|
14662
|
+
if (this.options.debug) {
|
|
14612
14663
|
console.log('📸 消息监听器已设置,正在监听 iframe 消息...');
|
|
14613
14664
|
}
|
|
14614
14665
|
}
|
|
@@ -14618,12 +14669,12 @@ class ScreenshotManager {
|
|
|
14618
14669
|
setupVisibilityChangeListener() {
|
|
14619
14670
|
document.addEventListener('visibilitychange', () => {
|
|
14620
14671
|
if (document.hidden) {
|
|
14621
|
-
if (
|
|
14672
|
+
if (this.options.debug) {
|
|
14622
14673
|
console.log('📸 页面隐藏,截图轮询已暂停');
|
|
14623
14674
|
}
|
|
14624
14675
|
}
|
|
14625
14676
|
else {
|
|
14626
|
-
if (
|
|
14677
|
+
if (this.options.debug) {
|
|
14627
14678
|
console.log('📸 页面显示,截图轮询已恢复');
|
|
14628
14679
|
}
|
|
14629
14680
|
}
|
|
@@ -14640,7 +14691,7 @@ class ScreenshotManager {
|
|
|
14640
14691
|
}
|
|
14641
14692
|
// 如果提供了发送消息的回调,保存它(用于后续发送二进制数据)
|
|
14642
14693
|
// 注意:消息来源验证在 setupMessageListener 中处理
|
|
14643
|
-
if (
|
|
14694
|
+
if (this.options.debug) {
|
|
14644
14695
|
console.log('📸 [iframe] 收到消息:', event.data);
|
|
14645
14696
|
}
|
|
14646
14697
|
// 尝试解析为二进制配置(新格式)
|
|
@@ -14654,7 +14705,7 @@ class ScreenshotManager {
|
|
|
14654
14705
|
if (isValid) {
|
|
14655
14706
|
// 启用截图功能
|
|
14656
14707
|
if (!this.isEnabled) {
|
|
14657
|
-
if (
|
|
14708
|
+
if (this.options.debug) {
|
|
14658
14709
|
console.log('📸 [iframe] 启用截图功能(二进制模式)');
|
|
14659
14710
|
}
|
|
14660
14711
|
this.isEnabled = true;
|
|
@@ -14664,7 +14715,7 @@ class ScreenshotManager {
|
|
|
14664
14715
|
// 计算剩余有效时间(毫秒)
|
|
14665
14716
|
const remainingTime = binaryConfig.ttl - currentTime;
|
|
14666
14717
|
// 启动或更新截图轮询
|
|
14667
|
-
if (
|
|
14718
|
+
if (this.options.debug) {
|
|
14668
14719
|
const remainingMinutes = Math.ceil(remainingTime / 60000);
|
|
14669
14720
|
console.log(`📸 [iframe] 设置轮询间隔: ${this.dynamicInterval}ms,剩余有效时间: ${remainingMinutes}分钟`);
|
|
14670
14721
|
}
|
|
@@ -14676,7 +14727,7 @@ class ScreenshotManager {
|
|
|
14676
14727
|
this.expirationTimer = null;
|
|
14677
14728
|
}
|
|
14678
14729
|
this.expirationTimer = setTimeout(() => {
|
|
14679
|
-
if (
|
|
14730
|
+
if (this.options.debug) {
|
|
14680
14731
|
console.log('📸 [iframe] 二进制配置已过期,停止截图');
|
|
14681
14732
|
}
|
|
14682
14733
|
this.stopScreenshot();
|
|
@@ -14687,7 +14738,7 @@ class ScreenshotManager {
|
|
|
14687
14738
|
}
|
|
14688
14739
|
else {
|
|
14689
14740
|
// 禁用截图功能(ttl == 0 或已过期)
|
|
14690
|
-
if (
|
|
14741
|
+
if (this.options.debug) {
|
|
14691
14742
|
if (binaryConfig.ttl === 0) {
|
|
14692
14743
|
console.log('📸 [iframe] ttl == 0,禁用截图功能');
|
|
14693
14744
|
}
|
|
@@ -14706,11 +14757,15 @@ class ScreenshotManager {
|
|
|
14706
14757
|
return;
|
|
14707
14758
|
}
|
|
14708
14759
|
// 如果不是二进制配置格式,记录错误
|
|
14709
|
-
|
|
14760
|
+
if (this.options.debug) {
|
|
14761
|
+
console.error('📸 [iframe] 解析配置失败:未识别的配置格式');
|
|
14762
|
+
}
|
|
14710
14763
|
this.uploadError = '解析配置失败:仅支持二进制配置格式';
|
|
14711
14764
|
}
|
|
14712
14765
|
catch (error) {
|
|
14713
|
-
|
|
14766
|
+
if (this.options.debug) {
|
|
14767
|
+
console.error('📸 [iframe] 处理消息失败:', error);
|
|
14768
|
+
}
|
|
14714
14769
|
this.uploadError = error instanceof Error ? error.message : String(error);
|
|
14715
14770
|
}
|
|
14716
14771
|
}
|
|
@@ -14749,17 +14804,19 @@ class ScreenshotManager {
|
|
|
14749
14804
|
*/
|
|
14750
14805
|
startScreenshot(customInterval) {
|
|
14751
14806
|
if (!this.isEnabled) {
|
|
14752
|
-
|
|
14807
|
+
if (this.options.debug) {
|
|
14808
|
+
console.warn('📸 截图功能已禁用,无法启动');
|
|
14809
|
+
}
|
|
14753
14810
|
return;
|
|
14754
14811
|
}
|
|
14755
14812
|
const currentInterval = customInterval || this.dynamicInterval || this.options.interval;
|
|
14756
14813
|
if (this.isRunning) {
|
|
14757
|
-
if (
|
|
14814
|
+
if (this.options.debug) {
|
|
14758
14815
|
console.log(`📸 更新轮询间隔: ${currentInterval}ms`);
|
|
14759
14816
|
}
|
|
14760
14817
|
this.stopScreenshot();
|
|
14761
14818
|
}
|
|
14762
|
-
if (
|
|
14819
|
+
if (this.options.debug) {
|
|
14763
14820
|
console.log(`📸 开始轮询截图,间隔: ${currentInterval}ms`);
|
|
14764
14821
|
}
|
|
14765
14822
|
this.isRunning = true;
|
|
@@ -14772,7 +14829,7 @@ class ScreenshotManager {
|
|
|
14772
14829
|
const scheduleNext = async () => {
|
|
14773
14830
|
// 如果上次任务还没完成,等待完成
|
|
14774
14831
|
if (!this.isCurrentTaskCompleted) {
|
|
14775
|
-
if (
|
|
14832
|
+
if (this.options.debug) {
|
|
14776
14833
|
console.log('📸 [定时] 等待上次任务完成...');
|
|
14777
14834
|
}
|
|
14778
14835
|
// 每100ms检查一次任务是否完成
|
|
@@ -14792,7 +14849,7 @@ class ScreenshotManager {
|
|
|
14792
14849
|
this.isCurrentTaskCompleted = false;
|
|
14793
14850
|
// 记录定时开始时间
|
|
14794
14851
|
const scheduleStartTime = performance.now();
|
|
14795
|
-
if (
|
|
14852
|
+
if (this.options.debug) {
|
|
14796
14853
|
console.log(`📸 [定时开始] 开始新一轮截图任务`);
|
|
14797
14854
|
}
|
|
14798
14855
|
try {
|
|
@@ -14824,7 +14881,7 @@ class ScreenshotManager {
|
|
|
14824
14881
|
const combinedBufferSize = combinedBuffer.byteLength;
|
|
14825
14882
|
const combineTime = performance.now() - combineStartTime;
|
|
14826
14883
|
// 打印大小信息
|
|
14827
|
-
if (
|
|
14884
|
+
if (this.options.debug) {
|
|
14828
14885
|
console.log('📸 [轮询-大小统计]');
|
|
14829
14886
|
console.log(` Base64 大小: ${base64Size} 字符`);
|
|
14830
14887
|
console.log(` 图片字节大小: ${(imageBufferSize / 1024).toFixed(2)} KB (${imageBufferSize} 字节)`);
|
|
@@ -14845,7 +14902,7 @@ class ScreenshotManager {
|
|
|
14845
14902
|
const sendCallbackTime = performance.now() - sendCallbackStartTime;
|
|
14846
14903
|
const totalSendTime = performance.now() - sendStartTime;
|
|
14847
14904
|
const totalTime = performance.now() - scheduleStartTime;
|
|
14848
|
-
if (
|
|
14905
|
+
if (this.options.debug) {
|
|
14849
14906
|
console.log('📸 [轮询] ✅ 二进制数据已发送到 iframe');
|
|
14850
14907
|
console.log(` ⏱️ 发送回调耗时: ${sendCallbackTime.toFixed(2)}ms`);
|
|
14851
14908
|
console.log(` ⏱️ 发送阶段总耗时: ${totalSendTime.toFixed(2)}ms`);
|
|
@@ -14854,7 +14911,9 @@ class ScreenshotManager {
|
|
|
14854
14911
|
}
|
|
14855
14912
|
}
|
|
14856
14913
|
catch (error) {
|
|
14857
|
-
|
|
14914
|
+
if (this.options.debug) {
|
|
14915
|
+
console.error('📸 [轮询] ❌ 处理二进制数据失败:', error);
|
|
14916
|
+
}
|
|
14858
14917
|
}
|
|
14859
14918
|
}
|
|
14860
14919
|
// 任务完成(无压缩模式)
|
|
@@ -14863,7 +14922,7 @@ class ScreenshotManager {
|
|
|
14863
14922
|
else if (this.currentBinaryConfig && this.options.compress) {
|
|
14864
14923
|
// 启用了压缩,等待 Worker 压缩完成后在 onmessage 中发送
|
|
14865
14924
|
// 任务完成标志会在压缩完成的回调中设置
|
|
14866
|
-
if (
|
|
14925
|
+
if (this.options.debug) {
|
|
14867
14926
|
console.log('📸 [轮询] 等待 Worker 压缩完成后发送到 iframe...');
|
|
14868
14927
|
}
|
|
14869
14928
|
}
|
|
@@ -14873,7 +14932,7 @@ class ScreenshotManager {
|
|
|
14873
14932
|
}
|
|
14874
14933
|
}
|
|
14875
14934
|
catch (error) {
|
|
14876
|
-
if (
|
|
14935
|
+
if (this.options.debug) {
|
|
14877
14936
|
console.error('📸 [轮询] 截图失败:', error);
|
|
14878
14937
|
}
|
|
14879
14938
|
// 任务失败,标记为完成
|
|
@@ -14898,7 +14957,7 @@ class ScreenshotManager {
|
|
|
14898
14957
|
if (!this.isRunning) {
|
|
14899
14958
|
return;
|
|
14900
14959
|
}
|
|
14901
|
-
if (
|
|
14960
|
+
if (this.options.debug) {
|
|
14902
14961
|
console.log('📸 停止轮询截图');
|
|
14903
14962
|
}
|
|
14904
14963
|
this.isRunning = false;
|
|
@@ -14915,7 +14974,9 @@ class ScreenshotManager {
|
|
|
14915
14974
|
*/
|
|
14916
14975
|
async captureOnce(force = false) {
|
|
14917
14976
|
if (!this.isEnabled && !force) {
|
|
14918
|
-
|
|
14977
|
+
if (this.options.debug) {
|
|
14978
|
+
console.warn('📸 截图功能已禁用,无法执行截图。如需测试,请先调用 enable(true) 启用截图功能');
|
|
14979
|
+
}
|
|
14919
14980
|
return false;
|
|
14920
14981
|
}
|
|
14921
14982
|
return await this.takeScreenshot();
|
|
@@ -14925,14 +14986,16 @@ class ScreenshotManager {
|
|
|
14925
14986
|
*/
|
|
14926
14987
|
async takeScreenshot(scheduleStartTime) {
|
|
14927
14988
|
if (!this.targetElement) {
|
|
14928
|
-
|
|
14989
|
+
if (this.options.debug) {
|
|
14990
|
+
console.warn('📸 目标元素不存在');
|
|
14991
|
+
}
|
|
14929
14992
|
return false;
|
|
14930
14993
|
}
|
|
14931
14994
|
// 记录截图开始时间
|
|
14932
14995
|
const screenshotStartTime = performance.now();
|
|
14933
14996
|
this.setupGlobalErrorHandlers();
|
|
14934
14997
|
try {
|
|
14935
|
-
if (
|
|
14998
|
+
if (this.options.debug) {
|
|
14936
14999
|
console.log(`📸 开始截图 #${this.screenshotCount + 1}...`);
|
|
14937
15000
|
if (scheduleStartTime) {
|
|
14938
15001
|
const waitTime = screenshotStartTime - scheduleStartTime;
|
|
@@ -14946,7 +15009,7 @@ class ScreenshotManager {
|
|
|
14946
15009
|
this.waitForFonts()
|
|
14947
15010
|
]);
|
|
14948
15011
|
const waitStylesTime = performance.now() - waitStylesStartTime;
|
|
14949
|
-
if (
|
|
15012
|
+
if (this.options.debug) {
|
|
14950
15013
|
console.log(` ⏱️ 等待样式和字体加载耗时: ${waitStylesTime.toFixed(2)}ms`);
|
|
14951
15014
|
}
|
|
14952
15015
|
// 等待元素完全渲染(特别是对于 modern-screenshot)
|
|
@@ -14955,12 +15018,12 @@ class ScreenshotManager {
|
|
|
14955
15018
|
requestAnimationFrame(() => resolve());
|
|
14956
15019
|
}));
|
|
14957
15020
|
const waitRenderTime = performance.now() - waitRenderStartTime;
|
|
14958
|
-
if (
|
|
15021
|
+
if (this.options.debug) {
|
|
14959
15022
|
console.log(` ⏱️ 等待渲染完成耗时: ${waitRenderTime.toFixed(2)}ms`);
|
|
14960
15023
|
}
|
|
14961
15024
|
// 选择截图引擎
|
|
14962
15025
|
const selectedEngine = this.options.engine || 'modern-screenshot';
|
|
14963
|
-
if (
|
|
15026
|
+
if (this.options.debug) {
|
|
14964
15027
|
console.log(`📸 使用截图引擎: ${selectedEngine}`);
|
|
14965
15028
|
}
|
|
14966
15029
|
// 优化:如果启用预加载,才预处理图片;否则让引擎按需加载
|
|
@@ -15000,7 +15063,7 @@ class ScreenshotManager {
|
|
|
15000
15063
|
dataUrl = await this.takeScreenshotWithModernScreenshot(this.targetElement);
|
|
15001
15064
|
}
|
|
15002
15065
|
const engineTime = performance.now() - engineStartTime;
|
|
15003
|
-
if (
|
|
15066
|
+
if (this.options.debug) {
|
|
15004
15067
|
console.log(` ⏱️ 截图引擎执行耗时: ${engineTime.toFixed(2)}ms`);
|
|
15005
15068
|
}
|
|
15006
15069
|
const timestamp = Date.now();
|
|
@@ -15014,7 +15077,7 @@ class ScreenshotManager {
|
|
|
15014
15077
|
const removed = this.screenshotHistory.shift();
|
|
15015
15078
|
// 强制 GC(如果可能)
|
|
15016
15079
|
if (removed && removed.length > 1000000) { // 大于1MB的字符串
|
|
15017
|
-
if (
|
|
15080
|
+
if (this.options.debug) {
|
|
15018
15081
|
console.log(`📸 清理旧截图,释放内存: ${Math.round(removed.length * 0.75 / 1024)} KB`);
|
|
15019
15082
|
}
|
|
15020
15083
|
}
|
|
@@ -15028,7 +15091,7 @@ class ScreenshotManager {
|
|
|
15028
15091
|
if (removed) {
|
|
15029
15092
|
const removedSize = removed.length;
|
|
15030
15093
|
totalSize -= removedSize;
|
|
15031
|
-
if (
|
|
15094
|
+
if (this.options.debug) {
|
|
15032
15095
|
console.warn(`📸 ⚠️ 历史记录总大小超过限制,清理最旧截图: ${Math.round(removedSize * 0.75 / 1024)} KB`);
|
|
15033
15096
|
}
|
|
15034
15097
|
}
|
|
@@ -15040,7 +15103,7 @@ class ScreenshotManager {
|
|
|
15040
15103
|
const screenshotTotalTime = performance.now() - screenshotStartTime;
|
|
15041
15104
|
// 打印基本信息
|
|
15042
15105
|
const base64Data = dataUrl.split(',')[1] || '';
|
|
15043
|
-
if (
|
|
15106
|
+
if (this.options.debug) {
|
|
15044
15107
|
console.log('📸 截图完成:');
|
|
15045
15108
|
console.log(`📸 编号: #${this.screenshotCount}`);
|
|
15046
15109
|
console.log(`📸 时间: ${new Date(timestamp).toLocaleTimeString()}`);
|
|
@@ -15059,7 +15122,7 @@ class ScreenshotManager {
|
|
|
15059
15122
|
// 确保 Worker 已创建
|
|
15060
15123
|
if (!this.worker) {
|
|
15061
15124
|
this.worker = this.createWorker();
|
|
15062
|
-
if (
|
|
15125
|
+
if (this.options.debug) {
|
|
15063
15126
|
if (this.worker) {
|
|
15064
15127
|
console.log('📸 Worker 已创建,准备压缩');
|
|
15065
15128
|
}
|
|
@@ -15071,7 +15134,7 @@ class ScreenshotManager {
|
|
|
15071
15134
|
if (this.worker) {
|
|
15072
15135
|
// 记录压缩开始时间
|
|
15073
15136
|
const compressStartTime = performance.now();
|
|
15074
|
-
if (
|
|
15137
|
+
if (this.options.debug) {
|
|
15075
15138
|
console.log('📸 发送到 WebWorker 进行压缩...');
|
|
15076
15139
|
}
|
|
15077
15140
|
// 保存原始 dataUrl 用于后续对比(在 Worker 压缩完成后)
|
|
@@ -15094,7 +15157,7 @@ class ScreenshotManager {
|
|
|
15094
15157
|
}
|
|
15095
15158
|
else {
|
|
15096
15159
|
// Worker 不可用,如果配置了二进制模式,直接发送原始截图
|
|
15097
|
-
if (
|
|
15160
|
+
if (this.options.debug) {
|
|
15098
15161
|
console.warn('📸 ⚠️ Worker 不可用,跳过压缩(使用原始截图)');
|
|
15099
15162
|
}
|
|
15100
15163
|
// Worker 不可用时,如果配置了二进制模式,立即发送原始截图
|
|
@@ -15110,7 +15173,7 @@ class ScreenshotManager {
|
|
|
15110
15173
|
data: combinedBuffer
|
|
15111
15174
|
};
|
|
15112
15175
|
this.sendToIframeCallback(message);
|
|
15113
|
-
if (
|
|
15176
|
+
if (this.options.debug) {
|
|
15114
15177
|
console.log('📸 [Worker 不可用] ✅ 原始截图已发送到 iframe');
|
|
15115
15178
|
}
|
|
15116
15179
|
}
|
|
@@ -15135,7 +15198,7 @@ class ScreenshotManager {
|
|
|
15135
15198
|
console.error('📸 截图失败:', err);
|
|
15136
15199
|
this.error = errorMessage;
|
|
15137
15200
|
}
|
|
15138
|
-
else if (
|
|
15201
|
+
else if (this.options.debug) {
|
|
15139
15202
|
console.warn('📸 截图遇到跨域问题(已忽略)');
|
|
15140
15203
|
}
|
|
15141
15204
|
return false;
|
|
@@ -15152,7 +15215,7 @@ class ScreenshotManager {
|
|
|
15152
15215
|
* 注意:snapdom 内部使用 worker 进行截图处理,会在后台线程执行,不会阻塞主线程
|
|
15153
15216
|
*/
|
|
15154
15217
|
async takeScreenshotWithSnapdom(element) {
|
|
15155
|
-
if (
|
|
15218
|
+
if (this.options.debug) {
|
|
15156
15219
|
console.log('📸 使用 snapdom 引擎截图...');
|
|
15157
15220
|
}
|
|
15158
15221
|
// 限制只截图可见区域(viewport),避免截图不可见区域
|
|
@@ -15192,7 +15255,7 @@ class ScreenshotManager {
|
|
|
15192
15255
|
// 简化方案:直接使用 body,但添加尺寸限制选项(如果 snapdom 支持)
|
|
15193
15256
|
// 如果不支持,则只能截图整个 body
|
|
15194
15257
|
targetElement = element;
|
|
15195
|
-
if (
|
|
15258
|
+
if (this.options.debug) {
|
|
15196
15259
|
console.log(`📸 注意:snapdom 将截图整个 body,建议使用 html2canvas 或 modern-screenshot 来限制可见区域`);
|
|
15197
15260
|
console.log(`📸 可见区域尺寸: ${window.innerWidth}x${window.innerHeight}`);
|
|
15198
15261
|
}
|
|
@@ -15209,7 +15272,7 @@ class ScreenshotManager {
|
|
|
15209
15272
|
elementRect.left >= 0 &&
|
|
15210
15273
|
elementRect.bottom <= window.innerHeight &&
|
|
15211
15274
|
elementRect.right <= window.innerWidth;
|
|
15212
|
-
if (!isFullyVisible &&
|
|
15275
|
+
if (!isFullyVisible && this.options.debug) {
|
|
15213
15276
|
console.warn(`📸 ⚠️ 元素部分不可见,snapdom 可能会截图整个元素(包括不可见部分)`);
|
|
15214
15277
|
console.warn(`📸 建议:使用 html2canvas 或 modern-screenshot 来限制可见区域`);
|
|
15215
15278
|
}
|
|
@@ -15227,12 +15290,12 @@ class ScreenshotManager {
|
|
|
15227
15290
|
proxyUrl = proxyUrl.endsWith('?') ? proxyUrl + 'url=' : proxyUrl + '?url=';
|
|
15228
15291
|
}
|
|
15229
15292
|
options.useProxy = proxyUrl;
|
|
15230
|
-
if (
|
|
15293
|
+
if (this.options.debug) {
|
|
15231
15294
|
console.log(`📸 使用代理服务器处理跨域图片: ${proxyUrl}`);
|
|
15232
15295
|
}
|
|
15233
15296
|
}
|
|
15234
15297
|
else {
|
|
15235
|
-
if (
|
|
15298
|
+
if (this.options.debug) {
|
|
15236
15299
|
if (!this.options.useProxy) {
|
|
15237
15300
|
console.log('📸 代理功能已禁用(useProxy: false)');
|
|
15238
15301
|
}
|
|
@@ -15274,7 +15337,7 @@ class ScreenshotManager {
|
|
|
15274
15337
|
parent.removeChild(container);
|
|
15275
15338
|
}
|
|
15276
15339
|
}
|
|
15277
|
-
if (
|
|
15340
|
+
if (this.options.debug) {
|
|
15278
15341
|
console.log(`📸 snapdom 截图成功!格式: ${outputFormat}, 尺寸: ${img.width}x${img.height}`);
|
|
15279
15342
|
}
|
|
15280
15343
|
return dataUrl;
|
|
@@ -15292,14 +15355,14 @@ class ScreenshotManager {
|
|
|
15292
15355
|
const errorName = error instanceof Error ? error.name : 'Unknown';
|
|
15293
15356
|
// 针对不同类型的错误给出具体提示
|
|
15294
15357
|
if (errorName === 'EncodingError' || errorMessage.includes('cannot be decoded')) {
|
|
15295
|
-
if (
|
|
15358
|
+
if (this.options.debug) {
|
|
15296
15359
|
console.warn('📸 ⚠️ 图片解码失败 - 这通常是因为跨域图片无法访问');
|
|
15297
15360
|
console.warn('📸 💡 解决方案:配置 proxyUrl 选项');
|
|
15298
15361
|
console.warn('📸 📖 参考: https://snapdom.dev/#cors');
|
|
15299
15362
|
}
|
|
15300
15363
|
}
|
|
15301
15364
|
else if (errorMessage.includes('CORS') || errorMessage.includes('cross-origin')) {
|
|
15302
|
-
if (
|
|
15365
|
+
if (this.options.debug) {
|
|
15303
15366
|
console.warn('📸 ⚠️ 检测到 CORS 错误,建议配置 proxyUrl 选项');
|
|
15304
15367
|
}
|
|
15305
15368
|
}
|
|
@@ -15324,7 +15387,7 @@ class ScreenshotManager {
|
|
|
15324
15387
|
* - 需要快速截图
|
|
15325
15388
|
*/
|
|
15326
15389
|
async takeScreenshotWithHtml2Canvas(element) {
|
|
15327
|
-
if (
|
|
15390
|
+
if (this.options.debug) {
|
|
15328
15391
|
console.log('📸 使用 html2canvas 引擎截图...');
|
|
15329
15392
|
}
|
|
15330
15393
|
try {
|
|
@@ -15378,7 +15441,7 @@ class ScreenshotManager {
|
|
|
15378
15441
|
: (isMobile ? 0.5 : 0.6), // 用户未配置,使用默认值
|
|
15379
15442
|
useCORS: this.options.enableCORS,
|
|
15380
15443
|
allowTaint: !this.options.enableCORS, // 如果启用 CORS,不允许 taint
|
|
15381
|
-
logging:
|
|
15444
|
+
logging: this.options.debug, // 使用配置的静默模式
|
|
15382
15445
|
// foreignObjectRendering: true, // ❌ 移除:可能导致跨域图片不显示
|
|
15383
15446
|
// removeContainer: true, // ❌ 移除:移到后面,避免重复定义
|
|
15384
15447
|
// 不设置 width 和 height,让 html2canvas 自动计算
|
|
@@ -15516,12 +15579,12 @@ class ScreenshotManager {
|
|
|
15516
15579
|
}
|
|
15517
15580
|
catch (e) {
|
|
15518
15581
|
// 忽略内联化错误
|
|
15519
|
-
if (
|
|
15582
|
+
if (this.options.debug) {
|
|
15520
15583
|
console.warn('📸 iOS 样式内联化失败:', e);
|
|
15521
15584
|
}
|
|
15522
15585
|
}
|
|
15523
15586
|
}
|
|
15524
|
-
if (
|
|
15587
|
+
if (this.options.debug) {
|
|
15525
15588
|
const styleLinks = clonedDoc.querySelectorAll('link[rel="stylesheet"]').length;
|
|
15526
15589
|
const styleTags = clonedDoc.querySelectorAll('style').length;
|
|
15527
15590
|
console.log(`📸 onclone: 已复制 ${styleLinks} 个样式表链接和 ${styleTags} 个内联样式标签${isIOS ? ' (iOS 模式:已内联化计算样式)' : ''}`);
|
|
@@ -15570,7 +15633,7 @@ class ScreenshotManager {
|
|
|
15570
15633
|
const cachedDataUrl = this.getCachedImage(originalSrc);
|
|
15571
15634
|
if (cachedDataUrl) {
|
|
15572
15635
|
img.src = cachedDataUrl;
|
|
15573
|
-
if (
|
|
15636
|
+
if (this.options.debug) {
|
|
15574
15637
|
console.log(`📸 使用缓存的图片: ${originalSrc.substring(0, 50)}...`);
|
|
15575
15638
|
}
|
|
15576
15639
|
return;
|
|
@@ -15579,7 +15642,7 @@ class ScreenshotManager {
|
|
|
15579
15642
|
// 构建代理 URL
|
|
15580
15643
|
try {
|
|
15581
15644
|
if (!this.options.proxyUrl) {
|
|
15582
|
-
if (
|
|
15645
|
+
if (this.options.debug) {
|
|
15583
15646
|
console.warn(`📸 ⚠️ 未配置代理 URL,跨域图片可能无法显示: ${originalSrc}`);
|
|
15584
15647
|
}
|
|
15585
15648
|
return;
|
|
@@ -15592,19 +15655,19 @@ class ScreenshotManager {
|
|
|
15592
15655
|
baseUrl = baseUrl.replace(/[?&]$/, '');
|
|
15593
15656
|
const proxyUrl = `${baseUrl}?${params.toString()}`;
|
|
15594
15657
|
img.src = proxyUrl;
|
|
15595
|
-
if (
|
|
15658
|
+
if (this.options.debug) {
|
|
15596
15659
|
console.log(`📸 使用代理 URL 替换跨域图片: ${originalSrc.substring(0, 50)}... -> ${proxyUrl.substring(0, 50)}...`);
|
|
15597
15660
|
}
|
|
15598
15661
|
}
|
|
15599
15662
|
catch (error) {
|
|
15600
|
-
if (
|
|
15663
|
+
if (this.options.debug) {
|
|
15601
15664
|
console.warn(`📸 ⚠️ 处理图片 URL 失败: ${originalSrc}`, error);
|
|
15602
15665
|
}
|
|
15603
15666
|
}
|
|
15604
15667
|
});
|
|
15605
15668
|
};
|
|
15606
15669
|
}
|
|
15607
|
-
if (
|
|
15670
|
+
if (this.options.debug) {
|
|
15608
15671
|
console.log(`📸 html2canvas 配置: 元素尺寸 ${elementWidth}x${elementHeight}, 质量 ${finalQuality.toFixed(2)}, 缩放 ${options.scale}`);
|
|
15609
15672
|
console.log(`📸 html2canvas 将自动计算截图尺寸(不限制 width/height)`);
|
|
15610
15673
|
console.log(`📸 用户配置质量: ${this.options.quality}, 实际使用质量: ${finalQuality.toFixed(2)}`);
|
|
@@ -15649,7 +15712,7 @@ class ScreenshotManager {
|
|
|
15649
15712
|
if (!dataUrl || dataUrl.length < 100) {
|
|
15650
15713
|
throw new Error('生成的截图数据无效或过短');
|
|
15651
15714
|
}
|
|
15652
|
-
if (
|
|
15715
|
+
if (this.options.debug) {
|
|
15653
15716
|
console.log(`📸 html2canvas 截图成功!格式: ${mimeType}, 尺寸: ${canvas.width}x${canvas.height}, 质量: ${finalQualityForExport?.toFixed(2) || 'N/A (PNG)'}`);
|
|
15654
15717
|
console.log(`📸 输出格式: ${mimeType}, 用户配置质量: ${this.options.quality}, 实际使用质量: ${finalQualityForExport?.toFixed(2) || 'N/A (PNG)'}`);
|
|
15655
15718
|
}
|
|
@@ -15657,7 +15720,7 @@ class ScreenshotManager {
|
|
|
15657
15720
|
}
|
|
15658
15721
|
catch (error) {
|
|
15659
15722
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
15660
|
-
if (
|
|
15723
|
+
if (this.options.debug) {
|
|
15661
15724
|
console.error('📸 html2canvas 截图失败:', errorMessage);
|
|
15662
15725
|
if (errorMessage.includes('CORS') || errorMessage.includes('cross-origin')) {
|
|
15663
15726
|
console.warn('📸 💡 建议:配置 proxyUrl 选项处理跨域图片');
|
|
@@ -15690,7 +15753,7 @@ class ScreenshotManager {
|
|
|
15690
15753
|
if (this.isScreenshotInProgress) {
|
|
15691
15754
|
// 队列最多保留 1 个请求,避免积压
|
|
15692
15755
|
if (this.screenshotQueue.length >= 1) {
|
|
15693
|
-
if (
|
|
15756
|
+
if (this.options.debug) {
|
|
15694
15757
|
console.log('📸 截图队列已满,跳过当前请求(等待队列处理)');
|
|
15695
15758
|
}
|
|
15696
15759
|
// 等待队列中的请求完成
|
|
@@ -15719,7 +15782,7 @@ class ScreenshotManager {
|
|
|
15719
15782
|
});
|
|
15720
15783
|
}
|
|
15721
15784
|
this.isScreenshotInProgress = true;
|
|
15722
|
-
if (
|
|
15785
|
+
if (this.options.debug) {
|
|
15723
15786
|
console.log('📸 使用 modern-screenshot 引擎截图(Worker 模式)...');
|
|
15724
15787
|
}
|
|
15725
15788
|
try {
|
|
@@ -15739,7 +15802,7 @@ class ScreenshotManager {
|
|
|
15739
15802
|
elementWidth = element.clientWidth || element.offsetWidth || element.scrollWidth;
|
|
15740
15803
|
elementHeight = element.clientHeight || element.offsetHeight || element.scrollHeight;
|
|
15741
15804
|
}
|
|
15742
|
-
if (
|
|
15805
|
+
if (this.options.debug) {
|
|
15743
15806
|
console.log(`📸 目标元素: ${element.tagName}${element.id ? '#' + element.id : ''}${element.className ? '.' + element.className.split(' ').join('.') : ''}`);
|
|
15744
15807
|
console.log(`📸 元素尺寸: ${elementWidth}x${elementHeight}`);
|
|
15745
15808
|
console.log(`📸 scrollWidth: ${element.scrollWidth}, scrollHeight: ${element.scrollHeight}`);
|
|
@@ -15773,7 +15836,7 @@ class ScreenshotManager {
|
|
|
15773
15836
|
// 检查内存缓存(优先使用缓存,带过期时间检查)
|
|
15774
15837
|
const cachedDataUrl = this.getCachedImage(url);
|
|
15775
15838
|
if (cachedDataUrl) {
|
|
15776
|
-
if (
|
|
15839
|
+
if (this.options.debug) {
|
|
15777
15840
|
console.log(`📸 ✅ 使用内存缓存图片: ${url.substring(0, 50)}...`);
|
|
15778
15841
|
}
|
|
15779
15842
|
return cachedDataUrl;
|
|
@@ -15825,7 +15888,7 @@ class ScreenshotManager {
|
|
|
15825
15888
|
}
|
|
15826
15889
|
}
|
|
15827
15890
|
catch (error) {
|
|
15828
|
-
if (
|
|
15891
|
+
if (this.options.debug) {
|
|
15829
15892
|
console.warn(`📸 代理处理图片失败: ${url.substring(0, 100)}...`, error);
|
|
15830
15893
|
}
|
|
15831
15894
|
// 失败时返回原 URL,让 modern-screenshot 自己处理
|
|
@@ -15874,7 +15937,7 @@ class ScreenshotManager {
|
|
|
15874
15937
|
// 按照 demo 的方式:只在 context 不存在时创建,之后一直复用
|
|
15875
15938
|
// 不进行复杂的检测和重新创建逻辑
|
|
15876
15939
|
if (!this.screenshotContext) {
|
|
15877
|
-
if (
|
|
15940
|
+
if (this.options.debug) {
|
|
15878
15941
|
console.log(`📸 创建截图 Worker 上下文...`);
|
|
15879
15942
|
console.log(`📸 Worker 模式: ${workerNumber} 个 Worker`);
|
|
15880
15943
|
}
|
|
@@ -15895,23 +15958,23 @@ class ScreenshotManager {
|
|
|
15895
15958
|
// 如果用户指定了 workerUrl,使用指定的 URL
|
|
15896
15959
|
if (this.options.workerUrl) {
|
|
15897
15960
|
simpleContextOptions.workerUrl = this.options.workerUrl;
|
|
15898
|
-
if (
|
|
15961
|
+
if (this.options.debug) {
|
|
15899
15962
|
console.log(`📸 使用指定的 Worker URL: ${this.options.workerUrl}`);
|
|
15900
15963
|
}
|
|
15901
15964
|
}
|
|
15902
15965
|
else {
|
|
15903
|
-
if (
|
|
15966
|
+
if (this.options.debug) {
|
|
15904
15967
|
console.log('📸 Worker URL 未指定,modern-screenshot 将自动处理');
|
|
15905
15968
|
}
|
|
15906
15969
|
}
|
|
15907
15970
|
try {
|
|
15908
15971
|
this.screenshotContext = await createContext$1(element, simpleContextOptions);
|
|
15909
|
-
if (
|
|
15972
|
+
if (this.options.debug) {
|
|
15910
15973
|
console.log('📸 Worker 上下文创建成功');
|
|
15911
15974
|
}
|
|
15912
15975
|
}
|
|
15913
15976
|
catch (error) {
|
|
15914
|
-
if (
|
|
15977
|
+
if (this.options.debug) {
|
|
15915
15978
|
console.error('📸 创建 Worker 上下文失败:', error);
|
|
15916
15979
|
}
|
|
15917
15980
|
throw error;
|
|
@@ -15921,7 +15984,7 @@ class ScreenshotManager {
|
|
|
15921
15984
|
// 按照 demo 的方式:使用 domToWebp 时传递配置参数
|
|
15922
15985
|
let dataUrl;
|
|
15923
15986
|
const outputFormat = this.options.outputFormat || 'webp';
|
|
15924
|
-
if (
|
|
15987
|
+
if (this.options.debug) {
|
|
15925
15988
|
console.log(`📸 使用 ${outputFormat.toUpperCase()} 格式截图(直接输出,无需转换)...`);
|
|
15926
15989
|
}
|
|
15927
15990
|
// 构建 domToWebp/domToJpeg/domToPng 的配置参数(和 demo 一致)
|
|
@@ -15956,14 +16019,14 @@ class ScreenshotManager {
|
|
|
15956
16019
|
if (!dataUrl || dataUrl.length < 100) {
|
|
15957
16020
|
throw new Error('生成的截图数据无效或过短');
|
|
15958
16021
|
}
|
|
15959
|
-
if (
|
|
16022
|
+
if (this.options.debug) {
|
|
15960
16023
|
console.log(`📸 ✅ modern-screenshot 截图成功(Worker 模式,${outputFormat.toUpperCase()} 格式)`);
|
|
15961
16024
|
}
|
|
15962
16025
|
return dataUrl;
|
|
15963
16026
|
}
|
|
15964
16027
|
catch (workerError) {
|
|
15965
16028
|
// Worker 模式失败,回退到普通模式(和 demo 一致)
|
|
15966
|
-
if (
|
|
16029
|
+
if (this.options.debug) {
|
|
15967
16030
|
console.warn('📸 Worker 模式失败,回退到普通模式:', workerError);
|
|
15968
16031
|
}
|
|
15969
16032
|
// 销毁失败的 context
|
|
@@ -16006,7 +16069,7 @@ class ScreenshotManager {
|
|
|
16006
16069
|
if (!dataUrl || dataUrl.length < 100) {
|
|
16007
16070
|
throw new Error('生成的截图数据无效或过短');
|
|
16008
16071
|
}
|
|
16009
|
-
if (
|
|
16072
|
+
if (this.options.debug) {
|
|
16010
16073
|
console.log(`📸 ✅ modern-screenshot 截图成功(普通模式,${outputFormat.toUpperCase()} 格式)`);
|
|
16011
16074
|
}
|
|
16012
16075
|
return dataUrl;
|
|
@@ -16014,7 +16077,7 @@ class ScreenshotManager {
|
|
|
16014
16077
|
}
|
|
16015
16078
|
catch (error) {
|
|
16016
16079
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
16017
|
-
if (
|
|
16080
|
+
if (this.options.debug) {
|
|
16018
16081
|
console.error('📸 modern-screenshot 截图失败:', errorMessage);
|
|
16019
16082
|
console.error('📸 元素信息:', {
|
|
16020
16083
|
width: rect.width,
|
|
@@ -16038,7 +16101,7 @@ class ScreenshotManager {
|
|
|
16038
16101
|
catch (error) {
|
|
16039
16102
|
// 外层错误处理:确保即使发生错误也释放锁
|
|
16040
16103
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
16041
|
-
if (
|
|
16104
|
+
if (this.options.debug) {
|
|
16042
16105
|
console.error('📸 modern-screenshot 截图异常:', errorMessage);
|
|
16043
16106
|
}
|
|
16044
16107
|
throw error;
|
|
@@ -16092,7 +16155,7 @@ class ScreenshotManager {
|
|
|
16092
16155
|
link.crossOrigin = 'anonymous';
|
|
16093
16156
|
document.head.appendChild(link);
|
|
16094
16157
|
this.preconnected = true;
|
|
16095
|
-
if (
|
|
16158
|
+
if (this.options.debug) {
|
|
16096
16159
|
console.log(`📸 ✅ 已预连接代理服务器: ${proxyOrigin}`);
|
|
16097
16160
|
}
|
|
16098
16161
|
}
|
|
@@ -16217,7 +16280,7 @@ class ScreenshotManager {
|
|
|
16217
16280
|
if (networkImages.length === 0) {
|
|
16218
16281
|
return;
|
|
16219
16282
|
}
|
|
16220
|
-
if (
|
|
16283
|
+
if (this.options.debug) {
|
|
16221
16284
|
const totalImages = images.length;
|
|
16222
16285
|
console.log(`📸 发现 ${networkImages.length}/${totalImages} 个可视区域内的跨域图片,开始并行预加载...`);
|
|
16223
16286
|
}
|
|
@@ -16225,7 +16288,7 @@ class ScreenshotManager {
|
|
|
16225
16288
|
// 只有当 useProxy 为 true 且 proxyUrl 存在时才使用代理
|
|
16226
16289
|
const shouldUseProxy = this.options.useProxy && this.options.proxyUrl && this.options.proxyUrl.trim() !== '';
|
|
16227
16290
|
if (shouldUseProxy) {
|
|
16228
|
-
if (
|
|
16291
|
+
if (this.options.debug) {
|
|
16229
16292
|
console.log(`📸 使用代理服务器处理跨域图片: ${this.options.proxyUrl}`);
|
|
16230
16293
|
}
|
|
16231
16294
|
// 优化:增加并发数,使用更大的批次
|
|
@@ -16253,13 +16316,13 @@ class ScreenshotManager {
|
|
|
16253
16316
|
}
|
|
16254
16317
|
catch (error) {
|
|
16255
16318
|
// 静默失败,不影响其他图片
|
|
16256
|
-
if (
|
|
16319
|
+
if (this.options.debug) {
|
|
16257
16320
|
console.warn(`📸 ❌ 代理预加载失败: ${originalSrc.substring(0, 50)}...`);
|
|
16258
16321
|
}
|
|
16259
16322
|
}
|
|
16260
16323
|
}));
|
|
16261
16324
|
}));
|
|
16262
|
-
if (
|
|
16325
|
+
if (this.options.debug) {
|
|
16263
16326
|
console.log(`📸 ✅ 预处理完成,缓存了 ${this.imageProxyCache.size} 个代理图片`);
|
|
16264
16327
|
}
|
|
16265
16328
|
}
|
|
@@ -16284,7 +16347,7 @@ class ScreenshotManager {
|
|
|
16284
16347
|
// 移除末尾的 ? 或 &(如果有)
|
|
16285
16348
|
baseUrl = baseUrl.replace(/[?&]$/, '');
|
|
16286
16349
|
const requestUrl = `${baseUrl}?${params.toString()}`;
|
|
16287
|
-
if (
|
|
16350
|
+
if (this.options.debug) {
|
|
16288
16351
|
console.log(`📸 🔄 代理请求 URL: ${requestUrl.substring(0, 200)}...`);
|
|
16289
16352
|
}
|
|
16290
16353
|
// 请求代理服务器
|
|
@@ -16303,7 +16366,7 @@ class ScreenshotManager {
|
|
|
16303
16366
|
const blob = await response.blob();
|
|
16304
16367
|
// 将 blob 转换为 data URL(用于 modern-screenshot 兼容性)
|
|
16305
16368
|
const dataUrl = await this.blobToDataUrl(blob);
|
|
16306
|
-
if (
|
|
16369
|
+
if (this.options.debug) {
|
|
16307
16370
|
console.log(`📸 ✅ 代理模式成功(已转换为 data URL): ${imageUrl.substring(0, 100)}...`);
|
|
16308
16371
|
}
|
|
16309
16372
|
return dataUrl;
|
|
@@ -16334,7 +16397,7 @@ class ScreenshotManager {
|
|
|
16334
16397
|
if (sizeMB > maxSizeMB) {
|
|
16335
16398
|
if (this.options.skipLargeImages) {
|
|
16336
16399
|
// 跳过过大的图片,返回占位符
|
|
16337
|
-
if (
|
|
16400
|
+
if (this.options.debug) {
|
|
16338
16401
|
console.warn(`📸 ⚠️ 跳过过大图片(${sizeMB.toFixed(2)}MB > ${maxSizeMB}MB): ${url.substring(0, 100)}...`);
|
|
16339
16402
|
}
|
|
16340
16403
|
// 返回一个 1x1 的透明占位符,避免截图失败
|
|
@@ -16342,7 +16405,7 @@ class ScreenshotManager {
|
|
|
16342
16405
|
}
|
|
16343
16406
|
else {
|
|
16344
16407
|
// 不跳过,但添加警告
|
|
16345
|
-
if (
|
|
16408
|
+
if (this.options.debug) {
|
|
16346
16409
|
console.warn(`📸 ⚠️ 图片较大(${sizeMB.toFixed(2)}MB),可能导致内存问题: ${url.substring(0, 100)}...`);
|
|
16347
16410
|
}
|
|
16348
16411
|
}
|
|
@@ -16356,14 +16419,14 @@ class ScreenshotManager {
|
|
|
16356
16419
|
if (blobSizeMB > maxSizeMB) {
|
|
16357
16420
|
if (this.options.skipLargeImages) {
|
|
16358
16421
|
// 跳过过大的图片,返回占位符
|
|
16359
|
-
if (
|
|
16422
|
+
if (this.options.debug) {
|
|
16360
16423
|
console.warn(`📸 ⚠️ 跳过过大图片(实际大小 ${blobSizeMB.toFixed(2)}MB > ${maxSizeMB}MB): ${url.substring(0, 100)}...`);
|
|
16361
16424
|
}
|
|
16362
16425
|
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
|
16363
16426
|
}
|
|
16364
16427
|
else {
|
|
16365
16428
|
// 不跳过,但添加警告
|
|
16366
|
-
if (
|
|
16429
|
+
if (this.options.debug) {
|
|
16367
16430
|
console.warn(`📸 ⚠️ 图片较大(实际大小 ${blobSizeMB.toFixed(2)}MB),可能导致内存问题: ${url.substring(0, 100)}...`);
|
|
16368
16431
|
}
|
|
16369
16432
|
}
|
|
@@ -16379,7 +16442,7 @@ class ScreenshotManager {
|
|
|
16379
16442
|
}
|
|
16380
16443
|
catch (error) {
|
|
16381
16444
|
// 下载失败,返回原 URL,让 modern-screenshot 自己处理
|
|
16382
|
-
if (
|
|
16445
|
+
if (this.options.debug) {
|
|
16383
16446
|
console.warn(`📸 ⚠️ 下载图片失败: ${url.substring(0, 100)}...`, error);
|
|
16384
16447
|
}
|
|
16385
16448
|
return url;
|
|
@@ -16810,7 +16873,7 @@ class ScreenshotManager {
|
|
|
16810
16873
|
// 更新历史记录为压缩后的数据
|
|
16811
16874
|
this.screenshotHistory[this.screenshotHistory.length - 1] = compressed.dataUrl;
|
|
16812
16875
|
// 打印压缩统计信息和 base64 对比
|
|
16813
|
-
if (
|
|
16876
|
+
if (this.options.debug) {
|
|
16814
16877
|
if (compressed.error) {
|
|
16815
16878
|
// 压缩失败,使用原始数据
|
|
16816
16879
|
console.warn('📸 [Worker 压缩] ⚠️ 压缩失败,使用原始截图');
|
|
@@ -16864,7 +16927,7 @@ class ScreenshotManager {
|
|
|
16864
16927
|
};
|
|
16865
16928
|
newWorker.onerror = (e) => {
|
|
16866
16929
|
console.error('📸 WebWorker 错误:', e);
|
|
16867
|
-
if (
|
|
16930
|
+
if (this.options.debug) {
|
|
16868
16931
|
console.warn('📸 Worker 压缩失败,使用原始截图');
|
|
16869
16932
|
}
|
|
16870
16933
|
// Worker 发生错误时,如果配置了二进制模式,发送原始截图
|
|
@@ -16880,7 +16943,7 @@ class ScreenshotManager {
|
|
|
16880
16943
|
data: combinedBuffer
|
|
16881
16944
|
};
|
|
16882
16945
|
this.sendToIframeCallback(message);
|
|
16883
|
-
if (
|
|
16946
|
+
if (this.options.debug) {
|
|
16884
16947
|
console.log('📸 [Worker 错误] ✅ 原始截图已发送到 iframe');
|
|
16885
16948
|
}
|
|
16886
16949
|
}
|
|
@@ -17045,7 +17108,7 @@ class ScreenshotManager {
|
|
|
17045
17108
|
async takeScreenshotAndSendBinary(config) {
|
|
17046
17109
|
// 如果已经在运行,先停止再重新开始
|
|
17047
17110
|
if (this.isRunning) {
|
|
17048
|
-
if (
|
|
17111
|
+
if (this.options.debug) {
|
|
17049
17112
|
console.log(`📸 更新轮询间隔: ${this.dynamicInterval || this.options.interval}ms`);
|
|
17050
17113
|
}
|
|
17051
17114
|
this.stopScreenshot();
|
|
@@ -17076,7 +17139,7 @@ class ScreenshotManager {
|
|
|
17076
17139
|
// 验证:base64Data(从 latestScreenshot 提取)和 imageBufferBase64(从 imageBuffer 转换)应该一致
|
|
17077
17140
|
const isBase64Same = base64Data === imageBufferBase64;
|
|
17078
17141
|
// 打印 imageBuffer 的 base64 编码(用于和接收端对比)
|
|
17079
|
-
if (
|
|
17142
|
+
if (this.options.debug) {
|
|
17080
17143
|
console.log('📸 [发送前] 数据流程分析:');
|
|
17081
17144
|
console.log(` latestScreenshot: ${latestScreenshot.substring(0, 50)}... (原始 data URL)`);
|
|
17082
17145
|
console.log(` base64Data (从 latestScreenshot 提取): 长度 ${base64Data.length} 字符`);
|
|
@@ -17102,7 +17165,7 @@ class ScreenshotManager {
|
|
|
17102
17165
|
const combinedBuffer = this.combineBinaryData(configBuffer, imageBuffer);
|
|
17103
17166
|
const combinedBufferSize = combinedBuffer.byteLength;
|
|
17104
17167
|
// 打印大小信息
|
|
17105
|
-
if (
|
|
17168
|
+
if (this.options.debug) {
|
|
17106
17169
|
console.log('📸 [大小统计]');
|
|
17107
17170
|
console.log(` Base64 大小: ${base64Size} 字符`);
|
|
17108
17171
|
console.log(` 图片字节大小: ${(imageBufferSize / 1024).toFixed(2)} KB (${imageBufferSize} 字节)`);
|
|
@@ -17116,7 +17179,7 @@ class ScreenshotManager {
|
|
|
17116
17179
|
data: combinedBuffer
|
|
17117
17180
|
};
|
|
17118
17181
|
this.sendToIframeCallback(message);
|
|
17119
|
-
if (
|
|
17182
|
+
if (this.options.debug) {
|
|
17120
17183
|
console.log('📸 [iframe] ✅ 二进制数据已发送到 iframe');
|
|
17121
17184
|
}
|
|
17122
17185
|
}
|
|
@@ -17130,14 +17193,14 @@ class ScreenshotManager {
|
|
|
17130
17193
|
}
|
|
17131
17194
|
}
|
|
17132
17195
|
else {
|
|
17133
|
-
if (
|
|
17196
|
+
if (this.options.debug) {
|
|
17134
17197
|
console.warn('📸 [iframe] 截图完成但未找到截图数据');
|
|
17135
17198
|
}
|
|
17136
17199
|
}
|
|
17137
17200
|
}
|
|
17138
17201
|
else {
|
|
17139
17202
|
// 启用了压缩,等待 Worker 压缩完成后在 onmessage 中自动发送
|
|
17140
|
-
if (
|
|
17203
|
+
if (this.options.debug) {
|
|
17141
17204
|
console.log('📸 [iframe] 等待 Worker 压缩完成后发送到 iframe...');
|
|
17142
17205
|
}
|
|
17143
17206
|
}
|
|
@@ -17167,7 +17230,7 @@ class ScreenshotManager {
|
|
|
17167
17230
|
const base64Data = dataUrl.split(',')[1] || '';
|
|
17168
17231
|
const base64Size = base64Data.length;
|
|
17169
17232
|
// 完整打印发送前的 base64 信息(用于调试)
|
|
17170
|
-
if (
|
|
17233
|
+
if (this.options.debug) {
|
|
17171
17234
|
console.log('📸 [发送前] Base64 信息:');
|
|
17172
17235
|
console.log(` Base64 长度: ${base64Size} 字符`);
|
|
17173
17236
|
console.log(` 📸 [发送前] 完整 Base64:`);
|
|
@@ -17191,7 +17254,7 @@ class ScreenshotManager {
|
|
|
17191
17254
|
const combinedBufferSize = combinedBuffer.byteLength;
|
|
17192
17255
|
const combineTime = performance.now() - combineStartTime;
|
|
17193
17256
|
// 打印大小信息
|
|
17194
|
-
if (
|
|
17257
|
+
if (this.options.debug) {
|
|
17195
17258
|
console.log('📸 [压缩后-大小统计]');
|
|
17196
17259
|
console.log(` Base64 大小: ${base64Size} 字符`);
|
|
17197
17260
|
console.log(` 图片字节大小: ${(imageBufferSize / 1024).toFixed(2)} KB (${imageBufferSize} 字节)`);
|
|
@@ -17214,7 +17277,7 @@ class ScreenshotManager {
|
|
|
17214
17277
|
if (scheduleStartTime) {
|
|
17215
17278
|
totalTime = performance.now() - scheduleStartTime;
|
|
17216
17279
|
}
|
|
17217
|
-
if (
|
|
17280
|
+
if (this.options.debug) {
|
|
17218
17281
|
console.log('📸 [压缩后] ✅ 二进制数据已发送到 iframe');
|
|
17219
17282
|
console.log(` ⏱️ 发送回调耗时: ${sendCallbackTime.toFixed(2)}ms`);
|
|
17220
17283
|
console.log(` ⏱️ 发送阶段总耗时: ${totalSendTime.toFixed(2)}ms`);
|
|
@@ -17317,8 +17380,8 @@ class ScreenshotManager {
|
|
|
17317
17380
|
if (newOptions.compress !== undefined) {
|
|
17318
17381
|
this.options.compress = newOptions.compress;
|
|
17319
17382
|
}
|
|
17320
|
-
if (newOptions.
|
|
17321
|
-
this.options.
|
|
17383
|
+
if (newOptions.debug !== undefined) {
|
|
17384
|
+
this.options.debug = newOptions.debug;
|
|
17322
17385
|
}
|
|
17323
17386
|
if (newOptions.proxyUrl !== undefined) {
|
|
17324
17387
|
this.options.proxyUrl = newOptions.proxyUrl;
|
|
@@ -17331,7 +17394,7 @@ class ScreenshotManager {
|
|
|
17331
17394
|
if (this.screenshotContext) {
|
|
17332
17395
|
try {
|
|
17333
17396
|
destroyContext(this.screenshotContext);
|
|
17334
|
-
if (
|
|
17397
|
+
if (this.options.debug) {
|
|
17335
17398
|
console.log(`📸 引擎已从 ${oldEngine} 切换到 ${newEngine},已清理旧 context`);
|
|
17336
17399
|
}
|
|
17337
17400
|
}
|
|
@@ -17340,12 +17403,12 @@ class ScreenshotManager {
|
|
|
17340
17403
|
}
|
|
17341
17404
|
this.screenshotContext = null;
|
|
17342
17405
|
}
|
|
17343
|
-
if (
|
|
17406
|
+
if (this.options.debug) {
|
|
17344
17407
|
console.log(`📸 截图引擎已更新: ${oldEngine} → ${newEngine}`);
|
|
17345
17408
|
console.log(`📸 下次截图时将使用新引擎: ${newEngine}`);
|
|
17346
17409
|
}
|
|
17347
17410
|
}
|
|
17348
|
-
else if (
|
|
17411
|
+
else if (this.options.debug) {
|
|
17349
17412
|
console.log('📸 截图配置已更新');
|
|
17350
17413
|
}
|
|
17351
17414
|
}
|
|
@@ -17445,7 +17508,7 @@ class ScreenshotManager {
|
|
|
17445
17508
|
const itemSizeMB = value.dataUrl.length * 0.75 / (1024 * 1024);
|
|
17446
17509
|
this.imageProxyCache.delete(key);
|
|
17447
17510
|
currentSizeMB -= itemSizeMB;
|
|
17448
|
-
if (
|
|
17511
|
+
if (this.options.debug) {
|
|
17449
17512
|
console.log(`📸 清理内存缓存(超过限制): ${key.substring(0, 50)}...`);
|
|
17450
17513
|
}
|
|
17451
17514
|
}
|
|
@@ -17470,7 +17533,7 @@ class ScreenshotManager {
|
|
|
17470
17533
|
expiredUrls.forEach(url => {
|
|
17471
17534
|
this.imageProxyCache.delete(url);
|
|
17472
17535
|
});
|
|
17473
|
-
if (expiredUrls.length > 0 &&
|
|
17536
|
+
if (expiredUrls.length > 0 && this.options.debug) {
|
|
17474
17537
|
console.log(`📸 清理了 ${expiredUrls.length} 个过期缓存`);
|
|
17475
17538
|
}
|
|
17476
17539
|
}
|
|
@@ -17482,7 +17545,7 @@ class ScreenshotManager {
|
|
|
17482
17545
|
// 每2分钟清理一次过期缓存(从5分钟改为2分钟,更频繁)
|
|
17483
17546
|
setInterval(() => {
|
|
17484
17547
|
this.cleanExpiredCache();
|
|
17485
|
-
if (
|
|
17548
|
+
if (this.options.debug) {
|
|
17486
17549
|
const memoryCacheSize = this.imageProxyCache.size;
|
|
17487
17550
|
const memoryCacheSizeMB = Array.from(this.imageProxyCache.values())
|
|
17488
17551
|
.reduce((sum, cached) => sum + cached.dataUrl.length * 0.75 / (1024 * 1024), 0);
|
|
@@ -20822,9 +20885,10 @@ class CustomerServiceSDK {
|
|
|
20822
20885
|
agent: config.agent,
|
|
20823
20886
|
timestamp: Date.now()
|
|
20824
20887
|
};
|
|
20825
|
-
//
|
|
20888
|
+
// 创建悬浮图标管理器(支持自定义位置和传送目标)
|
|
20826
20889
|
const iconPosition = options?.iconPosition || undefined;
|
|
20827
|
-
|
|
20890
|
+
const iconTarget = options?.target || undefined;
|
|
20891
|
+
this.iconManager = new IconManager(iconPosition, this.debug, iconTarget);
|
|
20828
20892
|
await this.iconManager.show();
|
|
20829
20893
|
// 创建iframe管理器(自动检测设备类型)
|
|
20830
20894
|
this.iframeManager = new IframeManager({
|
|
@@ -20864,10 +20928,10 @@ class CustomerServiceSDK {
|
|
|
20864
20928
|
// 默认截图目标为 document.body,可以通过配置自定义
|
|
20865
20929
|
const targetElement = document.body;
|
|
20866
20930
|
// 传入发送消息到 iframe 的回调函数
|
|
20867
|
-
// 将 debug
|
|
20931
|
+
// 将 debug 配置传递给截图管理器
|
|
20868
20932
|
const screenshotOptions = {
|
|
20869
20933
|
...config.screenshot,
|
|
20870
|
-
|
|
20934
|
+
debug: this.debug // 直接传递 debug 标志
|
|
20871
20935
|
};
|
|
20872
20936
|
this.screenshotManager = new ScreenshotManager(targetElement, screenshotOptions, (data) => {
|
|
20873
20937
|
// 通过 IframeManager 发送消息到 iframe
|
|
@@ -21082,8 +21146,9 @@ class CustomerServiceSDK {
|
|
|
21082
21146
|
return result.visitorId;
|
|
21083
21147
|
}
|
|
21084
21148
|
catch (error) {
|
|
21085
|
-
|
|
21086
|
-
|
|
21149
|
+
if (this.debug) {
|
|
21150
|
+
console.warn('❌ Failed to get device fingerprint, using fallback:', error);
|
|
21151
|
+
}
|
|
21087
21152
|
const fallbackId = 'device_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
|
|
21088
21153
|
if (this.debug) {
|
|
21089
21154
|
console.log('🆔 Fallback Device ID:', fallbackId);
|