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.cjs.js
CHANGED
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
// 直接使用base64字符串,避免打包后路径问题
|
|
6
6
|
const iconImage = 'data:image/png;base64,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';
|
|
7
7
|
class IconManager {
|
|
8
|
-
constructor(position, debug = false) {
|
|
8
|
+
constructor(position, debug = false, target) {
|
|
9
9
|
this.iconElement = null;
|
|
10
10
|
this.badgeElement = null;
|
|
11
11
|
this.onClickCallback = null;
|
|
@@ -23,8 +23,11 @@ class IconManager {
|
|
|
23
23
|
this.iconPosition = null; // 图标位置配置
|
|
24
24
|
this.debug = false; // debug 模式标志
|
|
25
25
|
this.isClickEnabled = true; // 是否允许点击(iframe 打开时禁用)
|
|
26
|
+
this.target = null; // 图标传送目标元素(可以是 HTMLElement 或选择器字符串)
|
|
26
27
|
this.iconPosition = position || null;
|
|
27
28
|
this.debug = debug;
|
|
29
|
+
// 保存 target(可以是 HTMLElement 或字符串选择器)
|
|
30
|
+
this.target = target || null;
|
|
28
31
|
}
|
|
29
32
|
/**
|
|
30
33
|
* 显示悬浮图标
|
|
@@ -123,8 +126,18 @@ class IconManager {
|
|
|
123
126
|
this.iconElement.appendChild(imgContainer);
|
|
124
127
|
// 添加拖动和点击事件
|
|
125
128
|
this.setupDragEvents();
|
|
126
|
-
//
|
|
127
|
-
|
|
129
|
+
// 添加到目标元素(如果 target 是字符串,需要重新查找,因为可能在初始化时元素还不存在)
|
|
130
|
+
const targetElement = this.getTargetElement();
|
|
131
|
+
if (targetElement) {
|
|
132
|
+
targetElement.appendChild(this.iconElement);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
// 如果目标元素不存在,回退到 document.body
|
|
136
|
+
document.body.appendChild(this.iconElement);
|
|
137
|
+
if (this.debug) {
|
|
138
|
+
console.warn('Target element not found, icon added to document.body');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
128
141
|
if (this.debug) {
|
|
129
142
|
console.log('CustomerSDK icon displayed');
|
|
130
143
|
}
|
|
@@ -497,6 +510,44 @@ class IconManager {
|
|
|
497
510
|
this.iconElement.style.cursor = 'pointer';
|
|
498
511
|
}
|
|
499
512
|
}
|
|
513
|
+
/**
|
|
514
|
+
* 获取目标元素(支持动态查找)
|
|
515
|
+
*/
|
|
516
|
+
getTargetElement() {
|
|
517
|
+
if (!this.target) {
|
|
518
|
+
return document.body;
|
|
519
|
+
}
|
|
520
|
+
// 如果 target 是字符串选择器,每次都需要重新查找(支持动态元素)
|
|
521
|
+
if (typeof this.target === 'string') {
|
|
522
|
+
const element = document.querySelector(this.target);
|
|
523
|
+
if (element) {
|
|
524
|
+
return element;
|
|
525
|
+
}
|
|
526
|
+
else {
|
|
527
|
+
// 如果元素不存在,回退到 document.body
|
|
528
|
+
if (this.debug) {
|
|
529
|
+
console.warn(`Target element not found: ${this.target}, falling back to document.body`);
|
|
530
|
+
}
|
|
531
|
+
return document.body;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
// 如果 target 是 HTMLElement
|
|
535
|
+
if (this.target instanceof HTMLElement) {
|
|
536
|
+
// 检查元素是否还在 DOM 中
|
|
537
|
+
if (document.body.contains(this.target)) {
|
|
538
|
+
return this.target;
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
// 如果元素不在 DOM 中,回退到 document.body
|
|
542
|
+
if (this.debug) {
|
|
543
|
+
console.warn('Target element no longer in DOM, falling back to document.body');
|
|
544
|
+
}
|
|
545
|
+
return document.body;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
// 默认回退到 document.body
|
|
549
|
+
return document.body;
|
|
550
|
+
}
|
|
500
551
|
/**
|
|
501
552
|
* 创建消息徽章(简化版)
|
|
502
553
|
*/
|
|
@@ -14544,7 +14595,7 @@ class ScreenshotManager {
|
|
|
14544
14595
|
useProxy: options.useProxy ?? true, // 默认启用代理(如果配置了proxyUrl)
|
|
14545
14596
|
engine: options.engine ?? 'modern-screenshot',
|
|
14546
14597
|
corsMode: options.corsMode ?? 'canvas-proxy',
|
|
14547
|
-
|
|
14598
|
+
debug: options.debug !== undefined ? options.debug : false, // 默认 false,不输出日志
|
|
14548
14599
|
maxRetries: options.maxRetries ?? 2,
|
|
14549
14600
|
preloadImages: options.preloadImages ?? false, // 默认不预加载,按需加载
|
|
14550
14601
|
maxConcurrentDownloads: options.maxConcurrentDownloads ?? 10, // 增加并发数
|
|
@@ -14564,9 +14615,9 @@ class ScreenshotManager {
|
|
|
14564
14615
|
this.setupMessageListener();
|
|
14565
14616
|
this.setupVisibilityChangeListener();
|
|
14566
14617
|
// 打印初始化信息
|
|
14567
|
-
if (
|
|
14618
|
+
if (this.options.debug) {
|
|
14568
14619
|
console.log('📸 ScreenshotManager 初始化完成');
|
|
14569
|
-
console.log(`📸 配置: interval=${this.options.interval}ms, engine=${this.options.engine},
|
|
14620
|
+
console.log(`📸 配置: interval=${this.options.interval}ms, engine=${this.options.engine}, debug=${this.options.debug}`);
|
|
14570
14621
|
console.log('📸 等待 iframe 发送 checkScreenshot 消息...');
|
|
14571
14622
|
}
|
|
14572
14623
|
// 启动缓存清理定时器
|
|
@@ -14589,7 +14640,7 @@ class ScreenshotManager {
|
|
|
14589
14640
|
if (this.screenshotContext) {
|
|
14590
14641
|
try {
|
|
14591
14642
|
destroyContext(this.screenshotContext);
|
|
14592
|
-
if (
|
|
14643
|
+
if (this.options.debug) {
|
|
14593
14644
|
console.log('📸 目标元素变化,清理 context');
|
|
14594
14645
|
}
|
|
14595
14646
|
}
|
|
@@ -14612,7 +14663,7 @@ class ScreenshotManager {
|
|
|
14612
14663
|
this.handleIframeMessage(event);
|
|
14613
14664
|
};
|
|
14614
14665
|
window.addEventListener('message', this.messageHandler);
|
|
14615
|
-
if (
|
|
14666
|
+
if (this.options.debug) {
|
|
14616
14667
|
console.log('📸 消息监听器已设置,正在监听 iframe 消息...');
|
|
14617
14668
|
}
|
|
14618
14669
|
}
|
|
@@ -14622,12 +14673,12 @@ class ScreenshotManager {
|
|
|
14622
14673
|
setupVisibilityChangeListener() {
|
|
14623
14674
|
document.addEventListener('visibilitychange', () => {
|
|
14624
14675
|
if (document.hidden) {
|
|
14625
|
-
if (
|
|
14676
|
+
if (this.options.debug) {
|
|
14626
14677
|
console.log('📸 页面隐藏,截图轮询已暂停');
|
|
14627
14678
|
}
|
|
14628
14679
|
}
|
|
14629
14680
|
else {
|
|
14630
|
-
if (
|
|
14681
|
+
if (this.options.debug) {
|
|
14631
14682
|
console.log('📸 页面显示,截图轮询已恢复');
|
|
14632
14683
|
}
|
|
14633
14684
|
}
|
|
@@ -14644,7 +14695,7 @@ class ScreenshotManager {
|
|
|
14644
14695
|
}
|
|
14645
14696
|
// 如果提供了发送消息的回调,保存它(用于后续发送二进制数据)
|
|
14646
14697
|
// 注意:消息来源验证在 setupMessageListener 中处理
|
|
14647
|
-
if (
|
|
14698
|
+
if (this.options.debug) {
|
|
14648
14699
|
console.log('📸 [iframe] 收到消息:', event.data);
|
|
14649
14700
|
}
|
|
14650
14701
|
// 尝试解析为二进制配置(新格式)
|
|
@@ -14658,7 +14709,7 @@ class ScreenshotManager {
|
|
|
14658
14709
|
if (isValid) {
|
|
14659
14710
|
// 启用截图功能
|
|
14660
14711
|
if (!this.isEnabled) {
|
|
14661
|
-
if (
|
|
14712
|
+
if (this.options.debug) {
|
|
14662
14713
|
console.log('📸 [iframe] 启用截图功能(二进制模式)');
|
|
14663
14714
|
}
|
|
14664
14715
|
this.isEnabled = true;
|
|
@@ -14668,7 +14719,7 @@ class ScreenshotManager {
|
|
|
14668
14719
|
// 计算剩余有效时间(毫秒)
|
|
14669
14720
|
const remainingTime = binaryConfig.ttl - currentTime;
|
|
14670
14721
|
// 启动或更新截图轮询
|
|
14671
|
-
if (
|
|
14722
|
+
if (this.options.debug) {
|
|
14672
14723
|
const remainingMinutes = Math.ceil(remainingTime / 60000);
|
|
14673
14724
|
console.log(`📸 [iframe] 设置轮询间隔: ${this.dynamicInterval}ms,剩余有效时间: ${remainingMinutes}分钟`);
|
|
14674
14725
|
}
|
|
@@ -14680,7 +14731,7 @@ class ScreenshotManager {
|
|
|
14680
14731
|
this.expirationTimer = null;
|
|
14681
14732
|
}
|
|
14682
14733
|
this.expirationTimer = setTimeout(() => {
|
|
14683
|
-
if (
|
|
14734
|
+
if (this.options.debug) {
|
|
14684
14735
|
console.log('📸 [iframe] 二进制配置已过期,停止截图');
|
|
14685
14736
|
}
|
|
14686
14737
|
this.stopScreenshot();
|
|
@@ -14691,7 +14742,7 @@ class ScreenshotManager {
|
|
|
14691
14742
|
}
|
|
14692
14743
|
else {
|
|
14693
14744
|
// 禁用截图功能(ttl == 0 或已过期)
|
|
14694
|
-
if (
|
|
14745
|
+
if (this.options.debug) {
|
|
14695
14746
|
if (binaryConfig.ttl === 0) {
|
|
14696
14747
|
console.log('📸 [iframe] ttl == 0,禁用截图功能');
|
|
14697
14748
|
}
|
|
@@ -14710,11 +14761,15 @@ class ScreenshotManager {
|
|
|
14710
14761
|
return;
|
|
14711
14762
|
}
|
|
14712
14763
|
// 如果不是二进制配置格式,记录错误
|
|
14713
|
-
|
|
14764
|
+
if (this.options.debug) {
|
|
14765
|
+
console.error('📸 [iframe] 解析配置失败:未识别的配置格式');
|
|
14766
|
+
}
|
|
14714
14767
|
this.uploadError = '解析配置失败:仅支持二进制配置格式';
|
|
14715
14768
|
}
|
|
14716
14769
|
catch (error) {
|
|
14717
|
-
|
|
14770
|
+
if (this.options.debug) {
|
|
14771
|
+
console.error('📸 [iframe] 处理消息失败:', error);
|
|
14772
|
+
}
|
|
14718
14773
|
this.uploadError = error instanceof Error ? error.message : String(error);
|
|
14719
14774
|
}
|
|
14720
14775
|
}
|
|
@@ -14753,17 +14808,19 @@ class ScreenshotManager {
|
|
|
14753
14808
|
*/
|
|
14754
14809
|
startScreenshot(customInterval) {
|
|
14755
14810
|
if (!this.isEnabled) {
|
|
14756
|
-
|
|
14811
|
+
if (this.options.debug) {
|
|
14812
|
+
console.warn('📸 截图功能已禁用,无法启动');
|
|
14813
|
+
}
|
|
14757
14814
|
return;
|
|
14758
14815
|
}
|
|
14759
14816
|
const currentInterval = customInterval || this.dynamicInterval || this.options.interval;
|
|
14760
14817
|
if (this.isRunning) {
|
|
14761
|
-
if (
|
|
14818
|
+
if (this.options.debug) {
|
|
14762
14819
|
console.log(`📸 更新轮询间隔: ${currentInterval}ms`);
|
|
14763
14820
|
}
|
|
14764
14821
|
this.stopScreenshot();
|
|
14765
14822
|
}
|
|
14766
|
-
if (
|
|
14823
|
+
if (this.options.debug) {
|
|
14767
14824
|
console.log(`📸 开始轮询截图,间隔: ${currentInterval}ms`);
|
|
14768
14825
|
}
|
|
14769
14826
|
this.isRunning = true;
|
|
@@ -14776,7 +14833,7 @@ class ScreenshotManager {
|
|
|
14776
14833
|
const scheduleNext = async () => {
|
|
14777
14834
|
// 如果上次任务还没完成,等待完成
|
|
14778
14835
|
if (!this.isCurrentTaskCompleted) {
|
|
14779
|
-
if (
|
|
14836
|
+
if (this.options.debug) {
|
|
14780
14837
|
console.log('📸 [定时] 等待上次任务完成...');
|
|
14781
14838
|
}
|
|
14782
14839
|
// 每100ms检查一次任务是否完成
|
|
@@ -14796,7 +14853,7 @@ class ScreenshotManager {
|
|
|
14796
14853
|
this.isCurrentTaskCompleted = false;
|
|
14797
14854
|
// 记录定时开始时间
|
|
14798
14855
|
const scheduleStartTime = performance.now();
|
|
14799
|
-
if (
|
|
14856
|
+
if (this.options.debug) {
|
|
14800
14857
|
console.log(`📸 [定时开始] 开始新一轮截图任务`);
|
|
14801
14858
|
}
|
|
14802
14859
|
try {
|
|
@@ -14828,7 +14885,7 @@ class ScreenshotManager {
|
|
|
14828
14885
|
const combinedBufferSize = combinedBuffer.byteLength;
|
|
14829
14886
|
const combineTime = performance.now() - combineStartTime;
|
|
14830
14887
|
// 打印大小信息
|
|
14831
|
-
if (
|
|
14888
|
+
if (this.options.debug) {
|
|
14832
14889
|
console.log('📸 [轮询-大小统计]');
|
|
14833
14890
|
console.log(` Base64 大小: ${base64Size} 字符`);
|
|
14834
14891
|
console.log(` 图片字节大小: ${(imageBufferSize / 1024).toFixed(2)} KB (${imageBufferSize} 字节)`);
|
|
@@ -14849,7 +14906,7 @@ class ScreenshotManager {
|
|
|
14849
14906
|
const sendCallbackTime = performance.now() - sendCallbackStartTime;
|
|
14850
14907
|
const totalSendTime = performance.now() - sendStartTime;
|
|
14851
14908
|
const totalTime = performance.now() - scheduleStartTime;
|
|
14852
|
-
if (
|
|
14909
|
+
if (this.options.debug) {
|
|
14853
14910
|
console.log('📸 [轮询] ✅ 二进制数据已发送到 iframe');
|
|
14854
14911
|
console.log(` ⏱️ 发送回调耗时: ${sendCallbackTime.toFixed(2)}ms`);
|
|
14855
14912
|
console.log(` ⏱️ 发送阶段总耗时: ${totalSendTime.toFixed(2)}ms`);
|
|
@@ -14858,7 +14915,9 @@ class ScreenshotManager {
|
|
|
14858
14915
|
}
|
|
14859
14916
|
}
|
|
14860
14917
|
catch (error) {
|
|
14861
|
-
|
|
14918
|
+
if (this.options.debug) {
|
|
14919
|
+
console.error('📸 [轮询] ❌ 处理二进制数据失败:', error);
|
|
14920
|
+
}
|
|
14862
14921
|
}
|
|
14863
14922
|
}
|
|
14864
14923
|
// 任务完成(无压缩模式)
|
|
@@ -14867,7 +14926,7 @@ class ScreenshotManager {
|
|
|
14867
14926
|
else if (this.currentBinaryConfig && this.options.compress) {
|
|
14868
14927
|
// 启用了压缩,等待 Worker 压缩完成后在 onmessage 中发送
|
|
14869
14928
|
// 任务完成标志会在压缩完成的回调中设置
|
|
14870
|
-
if (
|
|
14929
|
+
if (this.options.debug) {
|
|
14871
14930
|
console.log('📸 [轮询] 等待 Worker 压缩完成后发送到 iframe...');
|
|
14872
14931
|
}
|
|
14873
14932
|
}
|
|
@@ -14877,7 +14936,7 @@ class ScreenshotManager {
|
|
|
14877
14936
|
}
|
|
14878
14937
|
}
|
|
14879
14938
|
catch (error) {
|
|
14880
|
-
if (
|
|
14939
|
+
if (this.options.debug) {
|
|
14881
14940
|
console.error('📸 [轮询] 截图失败:', error);
|
|
14882
14941
|
}
|
|
14883
14942
|
// 任务失败,标记为完成
|
|
@@ -14902,7 +14961,7 @@ class ScreenshotManager {
|
|
|
14902
14961
|
if (!this.isRunning) {
|
|
14903
14962
|
return;
|
|
14904
14963
|
}
|
|
14905
|
-
if (
|
|
14964
|
+
if (this.options.debug) {
|
|
14906
14965
|
console.log('📸 停止轮询截图');
|
|
14907
14966
|
}
|
|
14908
14967
|
this.isRunning = false;
|
|
@@ -14919,7 +14978,9 @@ class ScreenshotManager {
|
|
|
14919
14978
|
*/
|
|
14920
14979
|
async captureOnce(force = false) {
|
|
14921
14980
|
if (!this.isEnabled && !force) {
|
|
14922
|
-
|
|
14981
|
+
if (this.options.debug) {
|
|
14982
|
+
console.warn('📸 截图功能已禁用,无法执行截图。如需测试,请先调用 enable(true) 启用截图功能');
|
|
14983
|
+
}
|
|
14923
14984
|
return false;
|
|
14924
14985
|
}
|
|
14925
14986
|
return await this.takeScreenshot();
|
|
@@ -14929,14 +14990,16 @@ class ScreenshotManager {
|
|
|
14929
14990
|
*/
|
|
14930
14991
|
async takeScreenshot(scheduleStartTime) {
|
|
14931
14992
|
if (!this.targetElement) {
|
|
14932
|
-
|
|
14993
|
+
if (this.options.debug) {
|
|
14994
|
+
console.warn('📸 目标元素不存在');
|
|
14995
|
+
}
|
|
14933
14996
|
return false;
|
|
14934
14997
|
}
|
|
14935
14998
|
// 记录截图开始时间
|
|
14936
14999
|
const screenshotStartTime = performance.now();
|
|
14937
15000
|
this.setupGlobalErrorHandlers();
|
|
14938
15001
|
try {
|
|
14939
|
-
if (
|
|
15002
|
+
if (this.options.debug) {
|
|
14940
15003
|
console.log(`📸 开始截图 #${this.screenshotCount + 1}...`);
|
|
14941
15004
|
if (scheduleStartTime) {
|
|
14942
15005
|
const waitTime = screenshotStartTime - scheduleStartTime;
|
|
@@ -14950,7 +15013,7 @@ class ScreenshotManager {
|
|
|
14950
15013
|
this.waitForFonts()
|
|
14951
15014
|
]);
|
|
14952
15015
|
const waitStylesTime = performance.now() - waitStylesStartTime;
|
|
14953
|
-
if (
|
|
15016
|
+
if (this.options.debug) {
|
|
14954
15017
|
console.log(` ⏱️ 等待样式和字体加载耗时: ${waitStylesTime.toFixed(2)}ms`);
|
|
14955
15018
|
}
|
|
14956
15019
|
// 等待元素完全渲染(特别是对于 modern-screenshot)
|
|
@@ -14959,12 +15022,12 @@ class ScreenshotManager {
|
|
|
14959
15022
|
requestAnimationFrame(() => resolve());
|
|
14960
15023
|
}));
|
|
14961
15024
|
const waitRenderTime = performance.now() - waitRenderStartTime;
|
|
14962
|
-
if (
|
|
15025
|
+
if (this.options.debug) {
|
|
14963
15026
|
console.log(` ⏱️ 等待渲染完成耗时: ${waitRenderTime.toFixed(2)}ms`);
|
|
14964
15027
|
}
|
|
14965
15028
|
// 选择截图引擎
|
|
14966
15029
|
const selectedEngine = this.options.engine || 'modern-screenshot';
|
|
14967
|
-
if (
|
|
15030
|
+
if (this.options.debug) {
|
|
14968
15031
|
console.log(`📸 使用截图引擎: ${selectedEngine}`);
|
|
14969
15032
|
}
|
|
14970
15033
|
// 优化:如果启用预加载,才预处理图片;否则让引擎按需加载
|
|
@@ -15004,7 +15067,7 @@ class ScreenshotManager {
|
|
|
15004
15067
|
dataUrl = await this.takeScreenshotWithModernScreenshot(this.targetElement);
|
|
15005
15068
|
}
|
|
15006
15069
|
const engineTime = performance.now() - engineStartTime;
|
|
15007
|
-
if (
|
|
15070
|
+
if (this.options.debug) {
|
|
15008
15071
|
console.log(` ⏱️ 截图引擎执行耗时: ${engineTime.toFixed(2)}ms`);
|
|
15009
15072
|
}
|
|
15010
15073
|
const timestamp = Date.now();
|
|
@@ -15018,7 +15081,7 @@ class ScreenshotManager {
|
|
|
15018
15081
|
const removed = this.screenshotHistory.shift();
|
|
15019
15082
|
// 强制 GC(如果可能)
|
|
15020
15083
|
if (removed && removed.length > 1000000) { // 大于1MB的字符串
|
|
15021
|
-
if (
|
|
15084
|
+
if (this.options.debug) {
|
|
15022
15085
|
console.log(`📸 清理旧截图,释放内存: ${Math.round(removed.length * 0.75 / 1024)} KB`);
|
|
15023
15086
|
}
|
|
15024
15087
|
}
|
|
@@ -15032,7 +15095,7 @@ class ScreenshotManager {
|
|
|
15032
15095
|
if (removed) {
|
|
15033
15096
|
const removedSize = removed.length;
|
|
15034
15097
|
totalSize -= removedSize;
|
|
15035
|
-
if (
|
|
15098
|
+
if (this.options.debug) {
|
|
15036
15099
|
console.warn(`📸 ⚠️ 历史记录总大小超过限制,清理最旧截图: ${Math.round(removedSize * 0.75 / 1024)} KB`);
|
|
15037
15100
|
}
|
|
15038
15101
|
}
|
|
@@ -15044,7 +15107,7 @@ class ScreenshotManager {
|
|
|
15044
15107
|
const screenshotTotalTime = performance.now() - screenshotStartTime;
|
|
15045
15108
|
// 打印基本信息
|
|
15046
15109
|
const base64Data = dataUrl.split(',')[1] || '';
|
|
15047
|
-
if (
|
|
15110
|
+
if (this.options.debug) {
|
|
15048
15111
|
console.log('📸 截图完成:');
|
|
15049
15112
|
console.log(`📸 编号: #${this.screenshotCount}`);
|
|
15050
15113
|
console.log(`📸 时间: ${new Date(timestamp).toLocaleTimeString()}`);
|
|
@@ -15063,7 +15126,7 @@ class ScreenshotManager {
|
|
|
15063
15126
|
// 确保 Worker 已创建
|
|
15064
15127
|
if (!this.worker) {
|
|
15065
15128
|
this.worker = this.createWorker();
|
|
15066
|
-
if (
|
|
15129
|
+
if (this.options.debug) {
|
|
15067
15130
|
if (this.worker) {
|
|
15068
15131
|
console.log('📸 Worker 已创建,准备压缩');
|
|
15069
15132
|
}
|
|
@@ -15075,7 +15138,7 @@ class ScreenshotManager {
|
|
|
15075
15138
|
if (this.worker) {
|
|
15076
15139
|
// 记录压缩开始时间
|
|
15077
15140
|
const compressStartTime = performance.now();
|
|
15078
|
-
if (
|
|
15141
|
+
if (this.options.debug) {
|
|
15079
15142
|
console.log('📸 发送到 WebWorker 进行压缩...');
|
|
15080
15143
|
}
|
|
15081
15144
|
// 保存原始 dataUrl 用于后续对比(在 Worker 压缩完成后)
|
|
@@ -15098,7 +15161,7 @@ class ScreenshotManager {
|
|
|
15098
15161
|
}
|
|
15099
15162
|
else {
|
|
15100
15163
|
// Worker 不可用,如果配置了二进制模式,直接发送原始截图
|
|
15101
|
-
if (
|
|
15164
|
+
if (this.options.debug) {
|
|
15102
15165
|
console.warn('📸 ⚠️ Worker 不可用,跳过压缩(使用原始截图)');
|
|
15103
15166
|
}
|
|
15104
15167
|
// Worker 不可用时,如果配置了二进制模式,立即发送原始截图
|
|
@@ -15114,7 +15177,7 @@ class ScreenshotManager {
|
|
|
15114
15177
|
data: combinedBuffer
|
|
15115
15178
|
};
|
|
15116
15179
|
this.sendToIframeCallback(message);
|
|
15117
|
-
if (
|
|
15180
|
+
if (this.options.debug) {
|
|
15118
15181
|
console.log('📸 [Worker 不可用] ✅ 原始截图已发送到 iframe');
|
|
15119
15182
|
}
|
|
15120
15183
|
}
|
|
@@ -15139,7 +15202,7 @@ class ScreenshotManager {
|
|
|
15139
15202
|
console.error('📸 截图失败:', err);
|
|
15140
15203
|
this.error = errorMessage;
|
|
15141
15204
|
}
|
|
15142
|
-
else if (
|
|
15205
|
+
else if (this.options.debug) {
|
|
15143
15206
|
console.warn('📸 截图遇到跨域问题(已忽略)');
|
|
15144
15207
|
}
|
|
15145
15208
|
return false;
|
|
@@ -15156,7 +15219,7 @@ class ScreenshotManager {
|
|
|
15156
15219
|
* 注意:snapdom 内部使用 worker 进行截图处理,会在后台线程执行,不会阻塞主线程
|
|
15157
15220
|
*/
|
|
15158
15221
|
async takeScreenshotWithSnapdom(element) {
|
|
15159
|
-
if (
|
|
15222
|
+
if (this.options.debug) {
|
|
15160
15223
|
console.log('📸 使用 snapdom 引擎截图...');
|
|
15161
15224
|
}
|
|
15162
15225
|
// 限制只截图可见区域(viewport),避免截图不可见区域
|
|
@@ -15196,7 +15259,7 @@ class ScreenshotManager {
|
|
|
15196
15259
|
// 简化方案:直接使用 body,但添加尺寸限制选项(如果 snapdom 支持)
|
|
15197
15260
|
// 如果不支持,则只能截图整个 body
|
|
15198
15261
|
targetElement = element;
|
|
15199
|
-
if (
|
|
15262
|
+
if (this.options.debug) {
|
|
15200
15263
|
console.log(`📸 注意:snapdom 将截图整个 body,建议使用 html2canvas 或 modern-screenshot 来限制可见区域`);
|
|
15201
15264
|
console.log(`📸 可见区域尺寸: ${window.innerWidth}x${window.innerHeight}`);
|
|
15202
15265
|
}
|
|
@@ -15213,7 +15276,7 @@ class ScreenshotManager {
|
|
|
15213
15276
|
elementRect.left >= 0 &&
|
|
15214
15277
|
elementRect.bottom <= window.innerHeight &&
|
|
15215
15278
|
elementRect.right <= window.innerWidth;
|
|
15216
|
-
if (!isFullyVisible &&
|
|
15279
|
+
if (!isFullyVisible && this.options.debug) {
|
|
15217
15280
|
console.warn(`📸 ⚠️ 元素部分不可见,snapdom 可能会截图整个元素(包括不可见部分)`);
|
|
15218
15281
|
console.warn(`📸 建议:使用 html2canvas 或 modern-screenshot 来限制可见区域`);
|
|
15219
15282
|
}
|
|
@@ -15231,12 +15294,12 @@ class ScreenshotManager {
|
|
|
15231
15294
|
proxyUrl = proxyUrl.endsWith('?') ? proxyUrl + 'url=' : proxyUrl + '?url=';
|
|
15232
15295
|
}
|
|
15233
15296
|
options.useProxy = proxyUrl;
|
|
15234
|
-
if (
|
|
15297
|
+
if (this.options.debug) {
|
|
15235
15298
|
console.log(`📸 使用代理服务器处理跨域图片: ${proxyUrl}`);
|
|
15236
15299
|
}
|
|
15237
15300
|
}
|
|
15238
15301
|
else {
|
|
15239
|
-
if (
|
|
15302
|
+
if (this.options.debug) {
|
|
15240
15303
|
if (!this.options.useProxy) {
|
|
15241
15304
|
console.log('📸 代理功能已禁用(useProxy: false)');
|
|
15242
15305
|
}
|
|
@@ -15278,7 +15341,7 @@ class ScreenshotManager {
|
|
|
15278
15341
|
parent.removeChild(container);
|
|
15279
15342
|
}
|
|
15280
15343
|
}
|
|
15281
|
-
if (
|
|
15344
|
+
if (this.options.debug) {
|
|
15282
15345
|
console.log(`📸 snapdom 截图成功!格式: ${outputFormat}, 尺寸: ${img.width}x${img.height}`);
|
|
15283
15346
|
}
|
|
15284
15347
|
return dataUrl;
|
|
@@ -15296,14 +15359,14 @@ class ScreenshotManager {
|
|
|
15296
15359
|
const errorName = error instanceof Error ? error.name : 'Unknown';
|
|
15297
15360
|
// 针对不同类型的错误给出具体提示
|
|
15298
15361
|
if (errorName === 'EncodingError' || errorMessage.includes('cannot be decoded')) {
|
|
15299
|
-
if (
|
|
15362
|
+
if (this.options.debug) {
|
|
15300
15363
|
console.warn('📸 ⚠️ 图片解码失败 - 这通常是因为跨域图片无法访问');
|
|
15301
15364
|
console.warn('📸 💡 解决方案:配置 proxyUrl 选项');
|
|
15302
15365
|
console.warn('📸 📖 参考: https://snapdom.dev/#cors');
|
|
15303
15366
|
}
|
|
15304
15367
|
}
|
|
15305
15368
|
else if (errorMessage.includes('CORS') || errorMessage.includes('cross-origin')) {
|
|
15306
|
-
if (
|
|
15369
|
+
if (this.options.debug) {
|
|
15307
15370
|
console.warn('📸 ⚠️ 检测到 CORS 错误,建议配置 proxyUrl 选项');
|
|
15308
15371
|
}
|
|
15309
15372
|
}
|
|
@@ -15328,7 +15391,7 @@ class ScreenshotManager {
|
|
|
15328
15391
|
* - 需要快速截图
|
|
15329
15392
|
*/
|
|
15330
15393
|
async takeScreenshotWithHtml2Canvas(element) {
|
|
15331
|
-
if (
|
|
15394
|
+
if (this.options.debug) {
|
|
15332
15395
|
console.log('📸 使用 html2canvas 引擎截图...');
|
|
15333
15396
|
}
|
|
15334
15397
|
try {
|
|
@@ -15382,7 +15445,7 @@ class ScreenshotManager {
|
|
|
15382
15445
|
: (isMobile ? 0.5 : 0.6), // 用户未配置,使用默认值
|
|
15383
15446
|
useCORS: this.options.enableCORS,
|
|
15384
15447
|
allowTaint: !this.options.enableCORS, // 如果启用 CORS,不允许 taint
|
|
15385
|
-
logging:
|
|
15448
|
+
logging: this.options.debug, // 使用配置的静默模式
|
|
15386
15449
|
// foreignObjectRendering: true, // ❌ 移除:可能导致跨域图片不显示
|
|
15387
15450
|
// removeContainer: true, // ❌ 移除:移到后面,避免重复定义
|
|
15388
15451
|
// 不设置 width 和 height,让 html2canvas 自动计算
|
|
@@ -15520,12 +15583,12 @@ class ScreenshotManager {
|
|
|
15520
15583
|
}
|
|
15521
15584
|
catch (e) {
|
|
15522
15585
|
// 忽略内联化错误
|
|
15523
|
-
if (
|
|
15586
|
+
if (this.options.debug) {
|
|
15524
15587
|
console.warn('📸 iOS 样式内联化失败:', e);
|
|
15525
15588
|
}
|
|
15526
15589
|
}
|
|
15527
15590
|
}
|
|
15528
|
-
if (
|
|
15591
|
+
if (this.options.debug) {
|
|
15529
15592
|
const styleLinks = clonedDoc.querySelectorAll('link[rel="stylesheet"]').length;
|
|
15530
15593
|
const styleTags = clonedDoc.querySelectorAll('style').length;
|
|
15531
15594
|
console.log(`📸 onclone: 已复制 ${styleLinks} 个样式表链接和 ${styleTags} 个内联样式标签${isIOS ? ' (iOS 模式:已内联化计算样式)' : ''}`);
|
|
@@ -15574,7 +15637,7 @@ class ScreenshotManager {
|
|
|
15574
15637
|
const cachedDataUrl = this.getCachedImage(originalSrc);
|
|
15575
15638
|
if (cachedDataUrl) {
|
|
15576
15639
|
img.src = cachedDataUrl;
|
|
15577
|
-
if (
|
|
15640
|
+
if (this.options.debug) {
|
|
15578
15641
|
console.log(`📸 使用缓存的图片: ${originalSrc.substring(0, 50)}...`);
|
|
15579
15642
|
}
|
|
15580
15643
|
return;
|
|
@@ -15583,7 +15646,7 @@ class ScreenshotManager {
|
|
|
15583
15646
|
// 构建代理 URL
|
|
15584
15647
|
try {
|
|
15585
15648
|
if (!this.options.proxyUrl) {
|
|
15586
|
-
if (
|
|
15649
|
+
if (this.options.debug) {
|
|
15587
15650
|
console.warn(`📸 ⚠️ 未配置代理 URL,跨域图片可能无法显示: ${originalSrc}`);
|
|
15588
15651
|
}
|
|
15589
15652
|
return;
|
|
@@ -15596,19 +15659,19 @@ class ScreenshotManager {
|
|
|
15596
15659
|
baseUrl = baseUrl.replace(/[?&]$/, '');
|
|
15597
15660
|
const proxyUrl = `${baseUrl}?${params.toString()}`;
|
|
15598
15661
|
img.src = proxyUrl;
|
|
15599
|
-
if (
|
|
15662
|
+
if (this.options.debug) {
|
|
15600
15663
|
console.log(`📸 使用代理 URL 替换跨域图片: ${originalSrc.substring(0, 50)}... -> ${proxyUrl.substring(0, 50)}...`);
|
|
15601
15664
|
}
|
|
15602
15665
|
}
|
|
15603
15666
|
catch (error) {
|
|
15604
|
-
if (
|
|
15667
|
+
if (this.options.debug) {
|
|
15605
15668
|
console.warn(`📸 ⚠️ 处理图片 URL 失败: ${originalSrc}`, error);
|
|
15606
15669
|
}
|
|
15607
15670
|
}
|
|
15608
15671
|
});
|
|
15609
15672
|
};
|
|
15610
15673
|
}
|
|
15611
|
-
if (
|
|
15674
|
+
if (this.options.debug) {
|
|
15612
15675
|
console.log(`📸 html2canvas 配置: 元素尺寸 ${elementWidth}x${elementHeight}, 质量 ${finalQuality.toFixed(2)}, 缩放 ${options.scale}`);
|
|
15613
15676
|
console.log(`📸 html2canvas 将自动计算截图尺寸(不限制 width/height)`);
|
|
15614
15677
|
console.log(`📸 用户配置质量: ${this.options.quality}, 实际使用质量: ${finalQuality.toFixed(2)}`);
|
|
@@ -15653,7 +15716,7 @@ class ScreenshotManager {
|
|
|
15653
15716
|
if (!dataUrl || dataUrl.length < 100) {
|
|
15654
15717
|
throw new Error('生成的截图数据无效或过短');
|
|
15655
15718
|
}
|
|
15656
|
-
if (
|
|
15719
|
+
if (this.options.debug) {
|
|
15657
15720
|
console.log(`📸 html2canvas 截图成功!格式: ${mimeType}, 尺寸: ${canvas.width}x${canvas.height}, 质量: ${finalQualityForExport?.toFixed(2) || 'N/A (PNG)'}`);
|
|
15658
15721
|
console.log(`📸 输出格式: ${mimeType}, 用户配置质量: ${this.options.quality}, 实际使用质量: ${finalQualityForExport?.toFixed(2) || 'N/A (PNG)'}`);
|
|
15659
15722
|
}
|
|
@@ -15661,7 +15724,7 @@ class ScreenshotManager {
|
|
|
15661
15724
|
}
|
|
15662
15725
|
catch (error) {
|
|
15663
15726
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
15664
|
-
if (
|
|
15727
|
+
if (this.options.debug) {
|
|
15665
15728
|
console.error('📸 html2canvas 截图失败:', errorMessage);
|
|
15666
15729
|
if (errorMessage.includes('CORS') || errorMessage.includes('cross-origin')) {
|
|
15667
15730
|
console.warn('📸 💡 建议:配置 proxyUrl 选项处理跨域图片');
|
|
@@ -15694,7 +15757,7 @@ class ScreenshotManager {
|
|
|
15694
15757
|
if (this.isScreenshotInProgress) {
|
|
15695
15758
|
// 队列最多保留 1 个请求,避免积压
|
|
15696
15759
|
if (this.screenshotQueue.length >= 1) {
|
|
15697
|
-
if (
|
|
15760
|
+
if (this.options.debug) {
|
|
15698
15761
|
console.log('📸 截图队列已满,跳过当前请求(等待队列处理)');
|
|
15699
15762
|
}
|
|
15700
15763
|
// 等待队列中的请求完成
|
|
@@ -15723,7 +15786,7 @@ class ScreenshotManager {
|
|
|
15723
15786
|
});
|
|
15724
15787
|
}
|
|
15725
15788
|
this.isScreenshotInProgress = true;
|
|
15726
|
-
if (
|
|
15789
|
+
if (this.options.debug) {
|
|
15727
15790
|
console.log('📸 使用 modern-screenshot 引擎截图(Worker 模式)...');
|
|
15728
15791
|
}
|
|
15729
15792
|
try {
|
|
@@ -15743,7 +15806,7 @@ class ScreenshotManager {
|
|
|
15743
15806
|
elementWidth = element.clientWidth || element.offsetWidth || element.scrollWidth;
|
|
15744
15807
|
elementHeight = element.clientHeight || element.offsetHeight || element.scrollHeight;
|
|
15745
15808
|
}
|
|
15746
|
-
if (
|
|
15809
|
+
if (this.options.debug) {
|
|
15747
15810
|
console.log(`📸 目标元素: ${element.tagName}${element.id ? '#' + element.id : ''}${element.className ? '.' + element.className.split(' ').join('.') : ''}`);
|
|
15748
15811
|
console.log(`📸 元素尺寸: ${elementWidth}x${elementHeight}`);
|
|
15749
15812
|
console.log(`📸 scrollWidth: ${element.scrollWidth}, scrollHeight: ${element.scrollHeight}`);
|
|
@@ -15777,7 +15840,7 @@ class ScreenshotManager {
|
|
|
15777
15840
|
// 检查内存缓存(优先使用缓存,带过期时间检查)
|
|
15778
15841
|
const cachedDataUrl = this.getCachedImage(url);
|
|
15779
15842
|
if (cachedDataUrl) {
|
|
15780
|
-
if (
|
|
15843
|
+
if (this.options.debug) {
|
|
15781
15844
|
console.log(`📸 ✅ 使用内存缓存图片: ${url.substring(0, 50)}...`);
|
|
15782
15845
|
}
|
|
15783
15846
|
return cachedDataUrl;
|
|
@@ -15829,7 +15892,7 @@ class ScreenshotManager {
|
|
|
15829
15892
|
}
|
|
15830
15893
|
}
|
|
15831
15894
|
catch (error) {
|
|
15832
|
-
if (
|
|
15895
|
+
if (this.options.debug) {
|
|
15833
15896
|
console.warn(`📸 代理处理图片失败: ${url.substring(0, 100)}...`, error);
|
|
15834
15897
|
}
|
|
15835
15898
|
// 失败时返回原 URL,让 modern-screenshot 自己处理
|
|
@@ -15878,7 +15941,7 @@ class ScreenshotManager {
|
|
|
15878
15941
|
// 按照 demo 的方式:只在 context 不存在时创建,之后一直复用
|
|
15879
15942
|
// 不进行复杂的检测和重新创建逻辑
|
|
15880
15943
|
if (!this.screenshotContext) {
|
|
15881
|
-
if (
|
|
15944
|
+
if (this.options.debug) {
|
|
15882
15945
|
console.log(`📸 创建截图 Worker 上下文...`);
|
|
15883
15946
|
console.log(`📸 Worker 模式: ${workerNumber} 个 Worker`);
|
|
15884
15947
|
}
|
|
@@ -15899,23 +15962,23 @@ class ScreenshotManager {
|
|
|
15899
15962
|
// 如果用户指定了 workerUrl,使用指定的 URL
|
|
15900
15963
|
if (this.options.workerUrl) {
|
|
15901
15964
|
simpleContextOptions.workerUrl = this.options.workerUrl;
|
|
15902
|
-
if (
|
|
15965
|
+
if (this.options.debug) {
|
|
15903
15966
|
console.log(`📸 使用指定的 Worker URL: ${this.options.workerUrl}`);
|
|
15904
15967
|
}
|
|
15905
15968
|
}
|
|
15906
15969
|
else {
|
|
15907
|
-
if (
|
|
15970
|
+
if (this.options.debug) {
|
|
15908
15971
|
console.log('📸 Worker URL 未指定,modern-screenshot 将自动处理');
|
|
15909
15972
|
}
|
|
15910
15973
|
}
|
|
15911
15974
|
try {
|
|
15912
15975
|
this.screenshotContext = await createContext$1(element, simpleContextOptions);
|
|
15913
|
-
if (
|
|
15976
|
+
if (this.options.debug) {
|
|
15914
15977
|
console.log('📸 Worker 上下文创建成功');
|
|
15915
15978
|
}
|
|
15916
15979
|
}
|
|
15917
15980
|
catch (error) {
|
|
15918
|
-
if (
|
|
15981
|
+
if (this.options.debug) {
|
|
15919
15982
|
console.error('📸 创建 Worker 上下文失败:', error);
|
|
15920
15983
|
}
|
|
15921
15984
|
throw error;
|
|
@@ -15925,7 +15988,7 @@ class ScreenshotManager {
|
|
|
15925
15988
|
// 按照 demo 的方式:使用 domToWebp 时传递配置参数
|
|
15926
15989
|
let dataUrl;
|
|
15927
15990
|
const outputFormat = this.options.outputFormat || 'webp';
|
|
15928
|
-
if (
|
|
15991
|
+
if (this.options.debug) {
|
|
15929
15992
|
console.log(`📸 使用 ${outputFormat.toUpperCase()} 格式截图(直接输出,无需转换)...`);
|
|
15930
15993
|
}
|
|
15931
15994
|
// 构建 domToWebp/domToJpeg/domToPng 的配置参数(和 demo 一致)
|
|
@@ -15960,14 +16023,14 @@ class ScreenshotManager {
|
|
|
15960
16023
|
if (!dataUrl || dataUrl.length < 100) {
|
|
15961
16024
|
throw new Error('生成的截图数据无效或过短');
|
|
15962
16025
|
}
|
|
15963
|
-
if (
|
|
16026
|
+
if (this.options.debug) {
|
|
15964
16027
|
console.log(`📸 ✅ modern-screenshot 截图成功(Worker 模式,${outputFormat.toUpperCase()} 格式)`);
|
|
15965
16028
|
}
|
|
15966
16029
|
return dataUrl;
|
|
15967
16030
|
}
|
|
15968
16031
|
catch (workerError) {
|
|
15969
16032
|
// Worker 模式失败,回退到普通模式(和 demo 一致)
|
|
15970
|
-
if (
|
|
16033
|
+
if (this.options.debug) {
|
|
15971
16034
|
console.warn('📸 Worker 模式失败,回退到普通模式:', workerError);
|
|
15972
16035
|
}
|
|
15973
16036
|
// 销毁失败的 context
|
|
@@ -16010,7 +16073,7 @@ class ScreenshotManager {
|
|
|
16010
16073
|
if (!dataUrl || dataUrl.length < 100) {
|
|
16011
16074
|
throw new Error('生成的截图数据无效或过短');
|
|
16012
16075
|
}
|
|
16013
|
-
if (
|
|
16076
|
+
if (this.options.debug) {
|
|
16014
16077
|
console.log(`📸 ✅ modern-screenshot 截图成功(普通模式,${outputFormat.toUpperCase()} 格式)`);
|
|
16015
16078
|
}
|
|
16016
16079
|
return dataUrl;
|
|
@@ -16018,7 +16081,7 @@ class ScreenshotManager {
|
|
|
16018
16081
|
}
|
|
16019
16082
|
catch (error) {
|
|
16020
16083
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
16021
|
-
if (
|
|
16084
|
+
if (this.options.debug) {
|
|
16022
16085
|
console.error('📸 modern-screenshot 截图失败:', errorMessage);
|
|
16023
16086
|
console.error('📸 元素信息:', {
|
|
16024
16087
|
width: rect.width,
|
|
@@ -16042,7 +16105,7 @@ class ScreenshotManager {
|
|
|
16042
16105
|
catch (error) {
|
|
16043
16106
|
// 外层错误处理:确保即使发生错误也释放锁
|
|
16044
16107
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
16045
|
-
if (
|
|
16108
|
+
if (this.options.debug) {
|
|
16046
16109
|
console.error('📸 modern-screenshot 截图异常:', errorMessage);
|
|
16047
16110
|
}
|
|
16048
16111
|
throw error;
|
|
@@ -16096,7 +16159,7 @@ class ScreenshotManager {
|
|
|
16096
16159
|
link.crossOrigin = 'anonymous';
|
|
16097
16160
|
document.head.appendChild(link);
|
|
16098
16161
|
this.preconnected = true;
|
|
16099
|
-
if (
|
|
16162
|
+
if (this.options.debug) {
|
|
16100
16163
|
console.log(`📸 ✅ 已预连接代理服务器: ${proxyOrigin}`);
|
|
16101
16164
|
}
|
|
16102
16165
|
}
|
|
@@ -16221,7 +16284,7 @@ class ScreenshotManager {
|
|
|
16221
16284
|
if (networkImages.length === 0) {
|
|
16222
16285
|
return;
|
|
16223
16286
|
}
|
|
16224
|
-
if (
|
|
16287
|
+
if (this.options.debug) {
|
|
16225
16288
|
const totalImages = images.length;
|
|
16226
16289
|
console.log(`📸 发现 ${networkImages.length}/${totalImages} 个可视区域内的跨域图片,开始并行预加载...`);
|
|
16227
16290
|
}
|
|
@@ -16229,7 +16292,7 @@ class ScreenshotManager {
|
|
|
16229
16292
|
// 只有当 useProxy 为 true 且 proxyUrl 存在时才使用代理
|
|
16230
16293
|
const shouldUseProxy = this.options.useProxy && this.options.proxyUrl && this.options.proxyUrl.trim() !== '';
|
|
16231
16294
|
if (shouldUseProxy) {
|
|
16232
|
-
if (
|
|
16295
|
+
if (this.options.debug) {
|
|
16233
16296
|
console.log(`📸 使用代理服务器处理跨域图片: ${this.options.proxyUrl}`);
|
|
16234
16297
|
}
|
|
16235
16298
|
// 优化:增加并发数,使用更大的批次
|
|
@@ -16257,13 +16320,13 @@ class ScreenshotManager {
|
|
|
16257
16320
|
}
|
|
16258
16321
|
catch (error) {
|
|
16259
16322
|
// 静默失败,不影响其他图片
|
|
16260
|
-
if (
|
|
16323
|
+
if (this.options.debug) {
|
|
16261
16324
|
console.warn(`📸 ❌ 代理预加载失败: ${originalSrc.substring(0, 50)}...`);
|
|
16262
16325
|
}
|
|
16263
16326
|
}
|
|
16264
16327
|
}));
|
|
16265
16328
|
}));
|
|
16266
|
-
if (
|
|
16329
|
+
if (this.options.debug) {
|
|
16267
16330
|
console.log(`📸 ✅ 预处理完成,缓存了 ${this.imageProxyCache.size} 个代理图片`);
|
|
16268
16331
|
}
|
|
16269
16332
|
}
|
|
@@ -16288,7 +16351,7 @@ class ScreenshotManager {
|
|
|
16288
16351
|
// 移除末尾的 ? 或 &(如果有)
|
|
16289
16352
|
baseUrl = baseUrl.replace(/[?&]$/, '');
|
|
16290
16353
|
const requestUrl = `${baseUrl}?${params.toString()}`;
|
|
16291
|
-
if (
|
|
16354
|
+
if (this.options.debug) {
|
|
16292
16355
|
console.log(`📸 🔄 代理请求 URL: ${requestUrl.substring(0, 200)}...`);
|
|
16293
16356
|
}
|
|
16294
16357
|
// 请求代理服务器
|
|
@@ -16307,7 +16370,7 @@ class ScreenshotManager {
|
|
|
16307
16370
|
const blob = await response.blob();
|
|
16308
16371
|
// 将 blob 转换为 data URL(用于 modern-screenshot 兼容性)
|
|
16309
16372
|
const dataUrl = await this.blobToDataUrl(blob);
|
|
16310
|
-
if (
|
|
16373
|
+
if (this.options.debug) {
|
|
16311
16374
|
console.log(`📸 ✅ 代理模式成功(已转换为 data URL): ${imageUrl.substring(0, 100)}...`);
|
|
16312
16375
|
}
|
|
16313
16376
|
return dataUrl;
|
|
@@ -16338,7 +16401,7 @@ class ScreenshotManager {
|
|
|
16338
16401
|
if (sizeMB > maxSizeMB) {
|
|
16339
16402
|
if (this.options.skipLargeImages) {
|
|
16340
16403
|
// 跳过过大的图片,返回占位符
|
|
16341
|
-
if (
|
|
16404
|
+
if (this.options.debug) {
|
|
16342
16405
|
console.warn(`📸 ⚠️ 跳过过大图片(${sizeMB.toFixed(2)}MB > ${maxSizeMB}MB): ${url.substring(0, 100)}...`);
|
|
16343
16406
|
}
|
|
16344
16407
|
// 返回一个 1x1 的透明占位符,避免截图失败
|
|
@@ -16346,7 +16409,7 @@ class ScreenshotManager {
|
|
|
16346
16409
|
}
|
|
16347
16410
|
else {
|
|
16348
16411
|
// 不跳过,但添加警告
|
|
16349
|
-
if (
|
|
16412
|
+
if (this.options.debug) {
|
|
16350
16413
|
console.warn(`📸 ⚠️ 图片较大(${sizeMB.toFixed(2)}MB),可能导致内存问题: ${url.substring(0, 100)}...`);
|
|
16351
16414
|
}
|
|
16352
16415
|
}
|
|
@@ -16360,14 +16423,14 @@ class ScreenshotManager {
|
|
|
16360
16423
|
if (blobSizeMB > maxSizeMB) {
|
|
16361
16424
|
if (this.options.skipLargeImages) {
|
|
16362
16425
|
// 跳过过大的图片,返回占位符
|
|
16363
|
-
if (
|
|
16426
|
+
if (this.options.debug) {
|
|
16364
16427
|
console.warn(`📸 ⚠️ 跳过过大图片(实际大小 ${blobSizeMB.toFixed(2)}MB > ${maxSizeMB}MB): ${url.substring(0, 100)}...`);
|
|
16365
16428
|
}
|
|
16366
16429
|
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
|
16367
16430
|
}
|
|
16368
16431
|
else {
|
|
16369
16432
|
// 不跳过,但添加警告
|
|
16370
|
-
if (
|
|
16433
|
+
if (this.options.debug) {
|
|
16371
16434
|
console.warn(`📸 ⚠️ 图片较大(实际大小 ${blobSizeMB.toFixed(2)}MB),可能导致内存问题: ${url.substring(0, 100)}...`);
|
|
16372
16435
|
}
|
|
16373
16436
|
}
|
|
@@ -16383,7 +16446,7 @@ class ScreenshotManager {
|
|
|
16383
16446
|
}
|
|
16384
16447
|
catch (error) {
|
|
16385
16448
|
// 下载失败,返回原 URL,让 modern-screenshot 自己处理
|
|
16386
|
-
if (
|
|
16449
|
+
if (this.options.debug) {
|
|
16387
16450
|
console.warn(`📸 ⚠️ 下载图片失败: ${url.substring(0, 100)}...`, error);
|
|
16388
16451
|
}
|
|
16389
16452
|
return url;
|
|
@@ -16814,7 +16877,7 @@ class ScreenshotManager {
|
|
|
16814
16877
|
// 更新历史记录为压缩后的数据
|
|
16815
16878
|
this.screenshotHistory[this.screenshotHistory.length - 1] = compressed.dataUrl;
|
|
16816
16879
|
// 打印压缩统计信息和 base64 对比
|
|
16817
|
-
if (
|
|
16880
|
+
if (this.options.debug) {
|
|
16818
16881
|
if (compressed.error) {
|
|
16819
16882
|
// 压缩失败,使用原始数据
|
|
16820
16883
|
console.warn('📸 [Worker 压缩] ⚠️ 压缩失败,使用原始截图');
|
|
@@ -16868,7 +16931,7 @@ class ScreenshotManager {
|
|
|
16868
16931
|
};
|
|
16869
16932
|
newWorker.onerror = (e) => {
|
|
16870
16933
|
console.error('📸 WebWorker 错误:', e);
|
|
16871
|
-
if (
|
|
16934
|
+
if (this.options.debug) {
|
|
16872
16935
|
console.warn('📸 Worker 压缩失败,使用原始截图');
|
|
16873
16936
|
}
|
|
16874
16937
|
// Worker 发生错误时,如果配置了二进制模式,发送原始截图
|
|
@@ -16884,7 +16947,7 @@ class ScreenshotManager {
|
|
|
16884
16947
|
data: combinedBuffer
|
|
16885
16948
|
};
|
|
16886
16949
|
this.sendToIframeCallback(message);
|
|
16887
|
-
if (
|
|
16950
|
+
if (this.options.debug) {
|
|
16888
16951
|
console.log('📸 [Worker 错误] ✅ 原始截图已发送到 iframe');
|
|
16889
16952
|
}
|
|
16890
16953
|
}
|
|
@@ -17049,7 +17112,7 @@ class ScreenshotManager {
|
|
|
17049
17112
|
async takeScreenshotAndSendBinary(config) {
|
|
17050
17113
|
// 如果已经在运行,先停止再重新开始
|
|
17051
17114
|
if (this.isRunning) {
|
|
17052
|
-
if (
|
|
17115
|
+
if (this.options.debug) {
|
|
17053
17116
|
console.log(`📸 更新轮询间隔: ${this.dynamicInterval || this.options.interval}ms`);
|
|
17054
17117
|
}
|
|
17055
17118
|
this.stopScreenshot();
|
|
@@ -17080,7 +17143,7 @@ class ScreenshotManager {
|
|
|
17080
17143
|
// 验证:base64Data(从 latestScreenshot 提取)和 imageBufferBase64(从 imageBuffer 转换)应该一致
|
|
17081
17144
|
const isBase64Same = base64Data === imageBufferBase64;
|
|
17082
17145
|
// 打印 imageBuffer 的 base64 编码(用于和接收端对比)
|
|
17083
|
-
if (
|
|
17146
|
+
if (this.options.debug) {
|
|
17084
17147
|
console.log('📸 [发送前] 数据流程分析:');
|
|
17085
17148
|
console.log(` latestScreenshot: ${latestScreenshot.substring(0, 50)}... (原始 data URL)`);
|
|
17086
17149
|
console.log(` base64Data (从 latestScreenshot 提取): 长度 ${base64Data.length} 字符`);
|
|
@@ -17106,7 +17169,7 @@ class ScreenshotManager {
|
|
|
17106
17169
|
const combinedBuffer = this.combineBinaryData(configBuffer, imageBuffer);
|
|
17107
17170
|
const combinedBufferSize = combinedBuffer.byteLength;
|
|
17108
17171
|
// 打印大小信息
|
|
17109
|
-
if (
|
|
17172
|
+
if (this.options.debug) {
|
|
17110
17173
|
console.log('📸 [大小统计]');
|
|
17111
17174
|
console.log(` Base64 大小: ${base64Size} 字符`);
|
|
17112
17175
|
console.log(` 图片字节大小: ${(imageBufferSize / 1024).toFixed(2)} KB (${imageBufferSize} 字节)`);
|
|
@@ -17120,7 +17183,7 @@ class ScreenshotManager {
|
|
|
17120
17183
|
data: combinedBuffer
|
|
17121
17184
|
};
|
|
17122
17185
|
this.sendToIframeCallback(message);
|
|
17123
|
-
if (
|
|
17186
|
+
if (this.options.debug) {
|
|
17124
17187
|
console.log('📸 [iframe] ✅ 二进制数据已发送到 iframe');
|
|
17125
17188
|
}
|
|
17126
17189
|
}
|
|
@@ -17134,14 +17197,14 @@ class ScreenshotManager {
|
|
|
17134
17197
|
}
|
|
17135
17198
|
}
|
|
17136
17199
|
else {
|
|
17137
|
-
if (
|
|
17200
|
+
if (this.options.debug) {
|
|
17138
17201
|
console.warn('📸 [iframe] 截图完成但未找到截图数据');
|
|
17139
17202
|
}
|
|
17140
17203
|
}
|
|
17141
17204
|
}
|
|
17142
17205
|
else {
|
|
17143
17206
|
// 启用了压缩,等待 Worker 压缩完成后在 onmessage 中自动发送
|
|
17144
|
-
if (
|
|
17207
|
+
if (this.options.debug) {
|
|
17145
17208
|
console.log('📸 [iframe] 等待 Worker 压缩完成后发送到 iframe...');
|
|
17146
17209
|
}
|
|
17147
17210
|
}
|
|
@@ -17171,7 +17234,7 @@ class ScreenshotManager {
|
|
|
17171
17234
|
const base64Data = dataUrl.split(',')[1] || '';
|
|
17172
17235
|
const base64Size = base64Data.length;
|
|
17173
17236
|
// 完整打印发送前的 base64 信息(用于调试)
|
|
17174
|
-
if (
|
|
17237
|
+
if (this.options.debug) {
|
|
17175
17238
|
console.log('📸 [发送前] Base64 信息:');
|
|
17176
17239
|
console.log(` Base64 长度: ${base64Size} 字符`);
|
|
17177
17240
|
console.log(` 📸 [发送前] 完整 Base64:`);
|
|
@@ -17195,7 +17258,7 @@ class ScreenshotManager {
|
|
|
17195
17258
|
const combinedBufferSize = combinedBuffer.byteLength;
|
|
17196
17259
|
const combineTime = performance.now() - combineStartTime;
|
|
17197
17260
|
// 打印大小信息
|
|
17198
|
-
if (
|
|
17261
|
+
if (this.options.debug) {
|
|
17199
17262
|
console.log('📸 [压缩后-大小统计]');
|
|
17200
17263
|
console.log(` Base64 大小: ${base64Size} 字符`);
|
|
17201
17264
|
console.log(` 图片字节大小: ${(imageBufferSize / 1024).toFixed(2)} KB (${imageBufferSize} 字节)`);
|
|
@@ -17218,7 +17281,7 @@ class ScreenshotManager {
|
|
|
17218
17281
|
if (scheduleStartTime) {
|
|
17219
17282
|
totalTime = performance.now() - scheduleStartTime;
|
|
17220
17283
|
}
|
|
17221
|
-
if (
|
|
17284
|
+
if (this.options.debug) {
|
|
17222
17285
|
console.log('📸 [压缩后] ✅ 二进制数据已发送到 iframe');
|
|
17223
17286
|
console.log(` ⏱️ 发送回调耗时: ${sendCallbackTime.toFixed(2)}ms`);
|
|
17224
17287
|
console.log(` ⏱️ 发送阶段总耗时: ${totalSendTime.toFixed(2)}ms`);
|
|
@@ -17321,8 +17384,8 @@ class ScreenshotManager {
|
|
|
17321
17384
|
if (newOptions.compress !== undefined) {
|
|
17322
17385
|
this.options.compress = newOptions.compress;
|
|
17323
17386
|
}
|
|
17324
|
-
if (newOptions.
|
|
17325
|
-
this.options.
|
|
17387
|
+
if (newOptions.debug !== undefined) {
|
|
17388
|
+
this.options.debug = newOptions.debug;
|
|
17326
17389
|
}
|
|
17327
17390
|
if (newOptions.proxyUrl !== undefined) {
|
|
17328
17391
|
this.options.proxyUrl = newOptions.proxyUrl;
|
|
@@ -17335,7 +17398,7 @@ class ScreenshotManager {
|
|
|
17335
17398
|
if (this.screenshotContext) {
|
|
17336
17399
|
try {
|
|
17337
17400
|
destroyContext(this.screenshotContext);
|
|
17338
|
-
if (
|
|
17401
|
+
if (this.options.debug) {
|
|
17339
17402
|
console.log(`📸 引擎已从 ${oldEngine} 切换到 ${newEngine},已清理旧 context`);
|
|
17340
17403
|
}
|
|
17341
17404
|
}
|
|
@@ -17344,12 +17407,12 @@ class ScreenshotManager {
|
|
|
17344
17407
|
}
|
|
17345
17408
|
this.screenshotContext = null;
|
|
17346
17409
|
}
|
|
17347
|
-
if (
|
|
17410
|
+
if (this.options.debug) {
|
|
17348
17411
|
console.log(`📸 截图引擎已更新: ${oldEngine} → ${newEngine}`);
|
|
17349
17412
|
console.log(`📸 下次截图时将使用新引擎: ${newEngine}`);
|
|
17350
17413
|
}
|
|
17351
17414
|
}
|
|
17352
|
-
else if (
|
|
17415
|
+
else if (this.options.debug) {
|
|
17353
17416
|
console.log('📸 截图配置已更新');
|
|
17354
17417
|
}
|
|
17355
17418
|
}
|
|
@@ -17449,7 +17512,7 @@ class ScreenshotManager {
|
|
|
17449
17512
|
const itemSizeMB = value.dataUrl.length * 0.75 / (1024 * 1024);
|
|
17450
17513
|
this.imageProxyCache.delete(key);
|
|
17451
17514
|
currentSizeMB -= itemSizeMB;
|
|
17452
|
-
if (
|
|
17515
|
+
if (this.options.debug) {
|
|
17453
17516
|
console.log(`📸 清理内存缓存(超过限制): ${key.substring(0, 50)}...`);
|
|
17454
17517
|
}
|
|
17455
17518
|
}
|
|
@@ -17474,7 +17537,7 @@ class ScreenshotManager {
|
|
|
17474
17537
|
expiredUrls.forEach(url => {
|
|
17475
17538
|
this.imageProxyCache.delete(url);
|
|
17476
17539
|
});
|
|
17477
|
-
if (expiredUrls.length > 0 &&
|
|
17540
|
+
if (expiredUrls.length > 0 && this.options.debug) {
|
|
17478
17541
|
console.log(`📸 清理了 ${expiredUrls.length} 个过期缓存`);
|
|
17479
17542
|
}
|
|
17480
17543
|
}
|
|
@@ -17486,7 +17549,7 @@ class ScreenshotManager {
|
|
|
17486
17549
|
// 每2分钟清理一次过期缓存(从5分钟改为2分钟,更频繁)
|
|
17487
17550
|
setInterval(() => {
|
|
17488
17551
|
this.cleanExpiredCache();
|
|
17489
|
-
if (
|
|
17552
|
+
if (this.options.debug) {
|
|
17490
17553
|
const memoryCacheSize = this.imageProxyCache.size;
|
|
17491
17554
|
const memoryCacheSizeMB = Array.from(this.imageProxyCache.values())
|
|
17492
17555
|
.reduce((sum, cached) => sum + cached.dataUrl.length * 0.75 / (1024 * 1024), 0);
|
|
@@ -20826,9 +20889,10 @@ class CustomerServiceSDK {
|
|
|
20826
20889
|
agent: config.agent,
|
|
20827
20890
|
timestamp: Date.now()
|
|
20828
20891
|
};
|
|
20829
|
-
//
|
|
20892
|
+
// 创建悬浮图标管理器(支持自定义位置和传送目标)
|
|
20830
20893
|
const iconPosition = options?.iconPosition || undefined;
|
|
20831
|
-
|
|
20894
|
+
const iconTarget = options?.target || undefined;
|
|
20895
|
+
this.iconManager = new IconManager(iconPosition, this.debug, iconTarget);
|
|
20832
20896
|
await this.iconManager.show();
|
|
20833
20897
|
// 创建iframe管理器(自动检测设备类型)
|
|
20834
20898
|
this.iframeManager = new IframeManager({
|
|
@@ -20868,10 +20932,10 @@ class CustomerServiceSDK {
|
|
|
20868
20932
|
// 默认截图目标为 document.body,可以通过配置自定义
|
|
20869
20933
|
const targetElement = document.body;
|
|
20870
20934
|
// 传入发送消息到 iframe 的回调函数
|
|
20871
|
-
// 将 debug
|
|
20935
|
+
// 将 debug 配置传递给截图管理器
|
|
20872
20936
|
const screenshotOptions = {
|
|
20873
20937
|
...config.screenshot,
|
|
20874
|
-
|
|
20938
|
+
debug: this.debug // 直接传递 debug 标志
|
|
20875
20939
|
};
|
|
20876
20940
|
this.screenshotManager = new ScreenshotManager(targetElement, screenshotOptions, (data) => {
|
|
20877
20941
|
// 通过 IframeManager 发送消息到 iframe
|
|
@@ -21086,8 +21150,9 @@ class CustomerServiceSDK {
|
|
|
21086
21150
|
return result.visitorId;
|
|
21087
21151
|
}
|
|
21088
21152
|
catch (error) {
|
|
21089
|
-
|
|
21090
|
-
|
|
21153
|
+
if (this.debug) {
|
|
21154
|
+
console.warn('❌ Failed to get device fingerprint, using fallback:', error);
|
|
21155
|
+
}
|
|
21091
21156
|
const fallbackId = 'device_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
|
|
21092
21157
|
if (this.debug) {
|
|
21093
21158
|
console.log('🆔 Fallback Device ID:', fallbackId);
|