customer-chat-sdk 1.0.42 → 1.0.43
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/ScreenshotManager.d.ts +3 -26
- package/dist/core/ScreenshotManager.d.ts.map +1 -1
- package/dist/customer-sdk.cjs.js +13 -234
- package/dist/customer-sdk.esm.js +13 -234
- package/dist/customer-sdk.min.js +2 -2
- package/dist/index.d.ts +3 -18
- package/dist/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/customer-sdk.esm.js
CHANGED
|
@@ -14310,11 +14310,8 @@ class ScreenshotManager {
|
|
|
14310
14310
|
this.error = null;
|
|
14311
14311
|
this.isEnabled = false;
|
|
14312
14312
|
// 上传相关状态
|
|
14313
|
-
this.isUploading = false;
|
|
14314
14313
|
this.uploadError = null;
|
|
14315
|
-
this.
|
|
14316
|
-
this.currentUploadConfig = null;
|
|
14317
|
-
this.currentBinaryConfig = null; // 二进制配置(新格式)
|
|
14314
|
+
this.currentBinaryConfig = null; // 二进制配置
|
|
14318
14315
|
this.sendToIframeCallback = null; // 发送消息到 iframe 的回调函数
|
|
14319
14316
|
// WebWorker 相关
|
|
14320
14317
|
this.worker = null;
|
|
@@ -14548,9 +14545,8 @@ class ScreenshotManager {
|
|
|
14548
14545
|
// 尝试解析为二进制配置(新格式)
|
|
14549
14546
|
const binaryConfig = this.parseBinaryConfig(event.data.data);
|
|
14550
14547
|
if (binaryConfig) {
|
|
14551
|
-
//
|
|
14548
|
+
// 二进制配置
|
|
14552
14549
|
this.currentBinaryConfig = binaryConfig;
|
|
14553
|
-
this.currentUploadConfig = null; // 清除旧格式配置
|
|
14554
14550
|
// 根据 ttl 判断是否开启截图功能
|
|
14555
14551
|
const currentTime = Date.now();
|
|
14556
14552
|
const isValid = binaryConfig.ttl > 0 && binaryConfig.ttl > currentTime;
|
|
@@ -14562,8 +14558,8 @@ class ScreenshotManager {
|
|
|
14562
14558
|
}
|
|
14563
14559
|
this.isEnabled = true;
|
|
14564
14560
|
}
|
|
14565
|
-
//
|
|
14566
|
-
this.dynamicInterval = this.options.interval;
|
|
14561
|
+
// 设置动态轮询间隔(使用配置中的 duration)
|
|
14562
|
+
this.dynamicInterval = binaryConfig.duration || this.options.interval;
|
|
14567
14563
|
// 计算剩余有效时间(毫秒)
|
|
14568
14564
|
const remainingTime = binaryConfig.ttl - currentTime;
|
|
14569
14565
|
// 启动或更新截图轮询
|
|
@@ -14608,73 +14604,9 @@ class ScreenshotManager {
|
|
|
14608
14604
|
}
|
|
14609
14605
|
return;
|
|
14610
14606
|
}
|
|
14611
|
-
//
|
|
14612
|
-
|
|
14613
|
-
|
|
14614
|
-
console.error('📸 [iframe] 解析配置失败');
|
|
14615
|
-
this.uploadError = '解析上传配置失败';
|
|
14616
|
-
return;
|
|
14617
|
-
}
|
|
14618
|
-
// 保存当前配置
|
|
14619
|
-
this.currentUploadConfig = config;
|
|
14620
|
-
this.currentBinaryConfig = null; // 清除二进制配置
|
|
14621
|
-
// 根据 ttl 判断是否开启截图功能
|
|
14622
|
-
// ttl == 0 表示禁用,ttl > 0 且大于当前时间表示有效
|
|
14623
|
-
const currentTime = Date.now();
|
|
14624
|
-
const isValid = config.ttl > 0 && config.ttl > currentTime;
|
|
14625
|
-
if (isValid) {
|
|
14626
|
-
// 启用截图功能
|
|
14627
|
-
if (!this.isEnabled) {
|
|
14628
|
-
if (!this.options.silentMode) {
|
|
14629
|
-
console.log('📸 [iframe] 启用截图功能');
|
|
14630
|
-
}
|
|
14631
|
-
this.isEnabled = true;
|
|
14632
|
-
}
|
|
14633
|
-
// 设置动态轮询间隔(使用 duration,单位:毫秒)
|
|
14634
|
-
this.dynamicInterval = config.duration || this.options.interval;
|
|
14635
|
-
// 计算剩余有效时间(毫秒)
|
|
14636
|
-
const remainingTime = config.ttl - currentTime;
|
|
14637
|
-
// 启动或更新截图轮询
|
|
14638
|
-
if (!this.options.silentMode) {
|
|
14639
|
-
const remainingMinutes = Math.ceil(remainingTime / 60000);
|
|
14640
|
-
console.log(`📸 [iframe] 设置轮询间隔: ${this.dynamicInterval}ms,剩余有效时间: ${remainingMinutes}分钟`);
|
|
14641
|
-
}
|
|
14642
|
-
// 先执行一次截图,等待完成后再上传
|
|
14643
|
-
this.takeScreenshotAndUpload(config);
|
|
14644
|
-
// 设置过期定时器
|
|
14645
|
-
if (this.expirationTimer) {
|
|
14646
|
-
clearTimeout(this.expirationTimer);
|
|
14647
|
-
this.expirationTimer = null;
|
|
14648
|
-
}
|
|
14649
|
-
this.expirationTimer = setTimeout(() => {
|
|
14650
|
-
if (!this.options.silentMode) {
|
|
14651
|
-
console.log('📸 [iframe] 上传配置已过期,停止截图');
|
|
14652
|
-
}
|
|
14653
|
-
this.stopScreenshot();
|
|
14654
|
-
this.isEnabled = false;
|
|
14655
|
-
this.currentUploadConfig = null;
|
|
14656
|
-
this.expirationTimer = null;
|
|
14657
|
-
}, remainingTime);
|
|
14658
|
-
}
|
|
14659
|
-
else {
|
|
14660
|
-
// 禁用截图功能(ttl == 0 或已过期)
|
|
14661
|
-
if (!this.options.silentMode) {
|
|
14662
|
-
if (config.ttl === 0) {
|
|
14663
|
-
console.log('📸 [iframe] ttl == 0,禁用截图功能');
|
|
14664
|
-
}
|
|
14665
|
-
else {
|
|
14666
|
-
console.log('📸 [iframe] ttl 已过期,禁用截图功能');
|
|
14667
|
-
}
|
|
14668
|
-
}
|
|
14669
|
-
this.stopScreenshot();
|
|
14670
|
-
this.isEnabled = false;
|
|
14671
|
-
this.currentUploadConfig = null;
|
|
14672
|
-
if (this.expirationTimer) {
|
|
14673
|
-
clearTimeout(this.expirationTimer);
|
|
14674
|
-
this.expirationTimer = null;
|
|
14675
|
-
}
|
|
14676
|
-
return;
|
|
14677
|
-
}
|
|
14607
|
+
// 如果不是二进制配置格式,记录错误
|
|
14608
|
+
console.error('📸 [iframe] 解析配置失败:未识别的配置格式');
|
|
14609
|
+
this.uploadError = '解析配置失败:仅支持二进制配置格式';
|
|
14678
14610
|
}
|
|
14679
14611
|
catch (error) {
|
|
14680
14612
|
console.error('📸 [iframe] 处理消息失败:', error);
|
|
@@ -14682,63 +14614,7 @@ class ScreenshotManager {
|
|
|
14682
14614
|
}
|
|
14683
14615
|
}
|
|
14684
14616
|
/**
|
|
14685
|
-
*
|
|
14686
|
-
*/
|
|
14687
|
-
async takeScreenshotAndUpload(config) {
|
|
14688
|
-
// 如果已经在运行,先停止再重新开始(更新间隔)
|
|
14689
|
-
if (this.isRunning) {
|
|
14690
|
-
if (!this.options.silentMode) {
|
|
14691
|
-
console.log(`📸 更新轮询间隔: ${this.dynamicInterval || this.options.interval}ms`);
|
|
14692
|
-
}
|
|
14693
|
-
this.stopScreenshot();
|
|
14694
|
-
}
|
|
14695
|
-
// 启动轮询
|
|
14696
|
-
this.startScreenshot(this.dynamicInterval || config.duration || this.options.interval);
|
|
14697
|
-
// 等待第一次截图完成
|
|
14698
|
-
try {
|
|
14699
|
-
const success = await this.takeScreenshot();
|
|
14700
|
-
if (success) {
|
|
14701
|
-
// 截图完成后,等待一小段时间确保数据已保存
|
|
14702
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
14703
|
-
// 获取最新截图并上传
|
|
14704
|
-
const latestScreenshot = this.getLatestScreenshot();
|
|
14705
|
-
if (latestScreenshot) {
|
|
14706
|
-
// 执行上传
|
|
14707
|
-
this.isUploading = true;
|
|
14708
|
-
this.uploadError = null;
|
|
14709
|
-
this.uploadScreenshot(latestScreenshot, config)
|
|
14710
|
-
.then((success) => {
|
|
14711
|
-
if (success) {
|
|
14712
|
-
if (!this.options.silentMode) {
|
|
14713
|
-
console.log('📸 [iframe] ✅ 截图上传成功');
|
|
14714
|
-
}
|
|
14715
|
-
}
|
|
14716
|
-
else {
|
|
14717
|
-
console.error('📸 [iframe] ❌ 截图上传失败');
|
|
14718
|
-
}
|
|
14719
|
-
})
|
|
14720
|
-
.catch((error) => {
|
|
14721
|
-
console.error('📸 [iframe] ❌ 上传异常:', error);
|
|
14722
|
-
this.uploadError = error instanceof Error ? error.message : String(error);
|
|
14723
|
-
})
|
|
14724
|
-
.finally(() => {
|
|
14725
|
-
this.isUploading = false;
|
|
14726
|
-
});
|
|
14727
|
-
}
|
|
14728
|
-
else {
|
|
14729
|
-
if (!this.options.silentMode) {
|
|
14730
|
-
console.warn('📸 [iframe] 截图完成但未找到截图数据');
|
|
14731
|
-
}
|
|
14732
|
-
}
|
|
14733
|
-
}
|
|
14734
|
-
}
|
|
14735
|
-
catch (error) {
|
|
14736
|
-
console.error('📸 [iframe] 截图失败:', error);
|
|
14737
|
-
this.uploadError = error instanceof Error ? error.message : String(error);
|
|
14738
|
-
}
|
|
14739
|
-
}
|
|
14740
|
-
/**
|
|
14741
|
-
* 解析二进制配置(新格式)
|
|
14617
|
+
* 解析二进制配置
|
|
14742
14618
|
*/
|
|
14743
14619
|
parseBinaryConfig(data) {
|
|
14744
14620
|
try {
|
|
@@ -14755,7 +14631,10 @@ class ScreenshotManager {
|
|
|
14755
14631
|
type: config.type,
|
|
14756
14632
|
topic: config.topic,
|
|
14757
14633
|
routingKey: config.routingKey,
|
|
14758
|
-
ttl: config.ttl
|
|
14634
|
+
ttl: config.ttl,
|
|
14635
|
+
duration: typeof config.duration === 'number' && config.duration > 0
|
|
14636
|
+
? config.duration
|
|
14637
|
+
: this.options.interval // 如果没有提供或无效,使用默认间隔
|
|
14759
14638
|
};
|
|
14760
14639
|
}
|
|
14761
14640
|
return null;
|
|
@@ -14765,38 +14644,6 @@ class ScreenshotManager {
|
|
|
14765
14644
|
return null;
|
|
14766
14645
|
}
|
|
14767
14646
|
}
|
|
14768
|
-
/**
|
|
14769
|
-
* 解析上传配置
|
|
14770
|
-
*/
|
|
14771
|
-
parseUploadConfig(data) {
|
|
14772
|
-
try {
|
|
14773
|
-
const configStr = typeof data === 'string' ? data : JSON.stringify(data);
|
|
14774
|
-
const config = JSON.parse(configStr);
|
|
14775
|
-
if (!config.uploadUrl || !config.contentType) {
|
|
14776
|
-
console.error('📸 [上传] 配置缺少必需字段:', config);
|
|
14777
|
-
return null;
|
|
14778
|
-
}
|
|
14779
|
-
// 确保 duration 存在,如果没有则使用默认值
|
|
14780
|
-
if (typeof config.duration !== 'number' || config.duration <= 0) {
|
|
14781
|
-
config.duration = this.options.interval;
|
|
14782
|
-
}
|
|
14783
|
-
// 确保 ttl 存在,如果没有则尝试从 expirationMinutes 转换(兼容旧格式)
|
|
14784
|
-
if (typeof config.ttl !== 'number') {
|
|
14785
|
-
if (typeof config.expirationMinutes === 'number' && config.expirationMinutes > 0) {
|
|
14786
|
-
// 兼容旧格式:将 expirationMinutes 转换为 ttl
|
|
14787
|
-
config.ttl = Date.now() + config.expirationMinutes * 60 * 1000;
|
|
14788
|
-
}
|
|
14789
|
-
else {
|
|
14790
|
-
config.ttl = 0; // 默认禁用
|
|
14791
|
-
}
|
|
14792
|
-
}
|
|
14793
|
-
return config;
|
|
14794
|
-
}
|
|
14795
|
-
catch (error) {
|
|
14796
|
-
console.error('📸 [上传] 解析配置失败:', error, '原始数据:', data);
|
|
14797
|
-
return null;
|
|
14798
|
-
}
|
|
14799
|
-
}
|
|
14800
14647
|
/**
|
|
14801
14648
|
* 开始轮询截图
|
|
14802
14649
|
*/
|
|
@@ -14826,16 +14673,6 @@ class ScreenshotManager {
|
|
|
14826
14673
|
if (this.isRunning && this.isEnabled && !document.hidden) {
|
|
14827
14674
|
try {
|
|
14828
14675
|
await this.takeScreenshot();
|
|
14829
|
-
// 如果配置了上传,且当前有上传配置,自动上传
|
|
14830
|
-
if (this.currentUploadConfig) {
|
|
14831
|
-
const latestScreenshot = this.getLatestScreenshot();
|
|
14832
|
-
if (latestScreenshot && !this.isUploading) {
|
|
14833
|
-
this.uploadScreenshot(latestScreenshot, this.currentUploadConfig)
|
|
14834
|
-
.catch((error) => {
|
|
14835
|
-
console.error('📸 [轮询] 自动上传失败:', error);
|
|
14836
|
-
});
|
|
14837
|
-
}
|
|
14838
|
-
}
|
|
14839
14676
|
// 如果配置了二进制模式,发送二进制数据
|
|
14840
14677
|
if (this.currentBinaryConfig) {
|
|
14841
14678
|
const latestScreenshot = this.getLatestScreenshot();
|
|
@@ -16918,62 +16755,6 @@ class ScreenshotManager {
|
|
|
16918
16755
|
this.globalRejectionHandler = null;
|
|
16919
16756
|
}
|
|
16920
16757
|
}
|
|
16921
|
-
/**
|
|
16922
|
-
* 上传截图到 S3
|
|
16923
|
-
*/
|
|
16924
|
-
async uploadScreenshot(dataUrl, config) {
|
|
16925
|
-
try {
|
|
16926
|
-
if (!this.options.silentMode) {
|
|
16927
|
-
console.log('📸 [上传] 开始上传截图...');
|
|
16928
|
-
}
|
|
16929
|
-
const blob = this.dataUrlToBlob(dataUrl, config.contentType);
|
|
16930
|
-
// 使用标准的 fetch 方法(与 demo 代码一致)
|
|
16931
|
-
const response = await fetch(config.uploadUrl, {
|
|
16932
|
-
method: 'PUT',
|
|
16933
|
-
body: blob,
|
|
16934
|
-
headers: {
|
|
16935
|
-
'Content-Type': config.contentType
|
|
16936
|
-
}
|
|
16937
|
-
});
|
|
16938
|
-
if (response.status === 200 || response.status === 204) {
|
|
16939
|
-
if (!this.options.silentMode) {
|
|
16940
|
-
console.log('📸 [上传] ✅ 上传成功');
|
|
16941
|
-
}
|
|
16942
|
-
this.uploadProgress.success++;
|
|
16943
|
-
return true;
|
|
16944
|
-
}
|
|
16945
|
-
else {
|
|
16946
|
-
const errorText = await response.text().catch(() => '');
|
|
16947
|
-
const errorMsg = `上传失败: HTTP ${response.status} ${response.statusText}${errorText ? ` - ${errorText.substring(0, 200)}` : ''}`;
|
|
16948
|
-
console.error('📸 [上传] ❌', errorMsg);
|
|
16949
|
-
this.uploadError = errorMsg;
|
|
16950
|
-
this.uploadProgress.failed++;
|
|
16951
|
-
return false;
|
|
16952
|
-
}
|
|
16953
|
-
}
|
|
16954
|
-
catch (error) {
|
|
16955
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
16956
|
-
console.error('📸 [上传] ❌ 上传异常:', errorMsg);
|
|
16957
|
-
this.uploadError = `上传异常: ${errorMsg}`;
|
|
16958
|
-
this.uploadProgress.failed++;
|
|
16959
|
-
return false;
|
|
16960
|
-
}
|
|
16961
|
-
}
|
|
16962
|
-
/**
|
|
16963
|
-
* 将 base64 data URL 转换为 Blob
|
|
16964
|
-
*/
|
|
16965
|
-
dataUrlToBlob(dataUrl, contentType) {
|
|
16966
|
-
const arr = dataUrl.split(',');
|
|
16967
|
-
const mimeMatch = arr[0].match(/:(.*?);/);
|
|
16968
|
-
const mime = mimeMatch ? mimeMatch[1] : contentType;
|
|
16969
|
-
const bstr = atob(arr[1]);
|
|
16970
|
-
let n = bstr.length;
|
|
16971
|
-
const u8arr = new Uint8Array(n);
|
|
16972
|
-
while (n--) {
|
|
16973
|
-
u8arr[n] = bstr.charCodeAt(n);
|
|
16974
|
-
}
|
|
16975
|
-
return new Blob([u8arr], { type: mime });
|
|
16976
|
-
}
|
|
16977
16758
|
/**
|
|
16978
16759
|
* 将 base64 data URL 转换为 ArrayBuffer
|
|
16979
16760
|
*/
|
|
@@ -17273,10 +17054,8 @@ class ScreenshotManager {
|
|
|
17273
17054
|
lastScreenshotTime: this.lastScreenshotTime,
|
|
17274
17055
|
error: this.error,
|
|
17275
17056
|
isEnabled: this.isEnabled,
|
|
17276
|
-
isUploading: this.isUploading,
|
|
17277
17057
|
uploadError: this.uploadError,
|
|
17278
|
-
|
|
17279
|
-
currentUploadConfig: this.currentUploadConfig
|
|
17058
|
+
currentBinaryConfig: this.currentBinaryConfig
|
|
17280
17059
|
};
|
|
17281
17060
|
}
|
|
17282
17061
|
}
|