customer-chat-sdk 1.4.2 → 1.4.4
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/customer-sdk.cjs.js +79 -552
- package/dist/customer-sdk.esm.js +77 -544
- package/dist/customer-sdk.min.js +4 -4
- package/dist/index.d.ts +68 -196
- package/dist/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/cd55183185a9b3ae.png +0 -0
- package/dist/core/IconManager.interact.example.d.ts +0 -36
- package/dist/core/IconManager.interact.example.d.ts.map +0 -1
- package/dist/core/IframeManager.d.ts +0 -111
- package/dist/core/IframeManager.d.ts.map +0 -1
- package/dist/core/SimpleSDK.d.ts +0 -111
- package/dist/core/SimpleSDK.d.ts.map +0 -1
- package/dist/simple.d.ts +0 -14
- package/dist/simple.d.ts.map +0 -1
package/dist/customer-sdk.cjs.js
CHANGED
|
@@ -29354,7 +29354,7 @@ function requireBlowfish () {
|
|
|
29354
29354
|
|
|
29355
29355
|
var cryptoJsExports = cryptoJs.exports;
|
|
29356
29356
|
|
|
29357
|
-
class CustomerSDK {
|
|
29357
|
+
let CustomerSDK$1 = class CustomerSDK {
|
|
29358
29358
|
constructor() {
|
|
29359
29359
|
this.iconManager = null;
|
|
29360
29360
|
this.screenshotManager = null;
|
|
@@ -29639,631 +29639,158 @@ class CustomerSDK {
|
|
|
29639
29639
|
console.log('CustomerSDK destroyed');
|
|
29640
29640
|
}
|
|
29641
29641
|
}
|
|
29642
|
-
}
|
|
29642
|
+
};
|
|
29643
29643
|
|
|
29644
29644
|
/**
|
|
29645
|
-
*
|
|
29646
|
-
* 只负责悬浮图标和iframe管理,不处理WebSocket连接
|
|
29647
|
-
* 所有聊天逻辑都在iframe中处理
|
|
29645
|
+
* 全局 CustomerSDK 单例实例
|
|
29648
29646
|
*/
|
|
29649
|
-
class CustomerServiceSDK {
|
|
29650
|
-
constructor() {
|
|
29651
|
-
this.iconManager = null;
|
|
29652
|
-
this.screenshotManager = null;
|
|
29653
|
-
this.config = null;
|
|
29654
|
-
this.isInitialized = false;
|
|
29655
|
-
this.isInitializing = false; // 初始化锁,防止并发初始化
|
|
29656
|
-
this.initResult = null; // 保存初始化结果
|
|
29657
|
-
this.debug = false; // debug 模式标志
|
|
29658
|
-
this.lastIconConfig = null; // 保存上一次的图标配置
|
|
29659
|
-
}
|
|
29660
|
-
/**
|
|
29661
|
-
* 初始化 SDK
|
|
29662
|
-
* @param config SDK配置
|
|
29663
|
-
* @param options UI选项 或 截图回调(可选)
|
|
29664
|
-
* @param forceReinit 是否强制重新初始化(用于更新token等配置)
|
|
29665
|
-
* @returns 返回初始化信息(包含设备ID等)
|
|
29666
|
-
*/
|
|
29667
|
-
async init(config, options, forceReinit = false) {
|
|
29668
|
-
// 防止并发初始化
|
|
29669
|
-
if (this.isInitializing) {
|
|
29670
|
-
throw new Error('SDK is already initializing. Please wait for the current initialization to complete.');
|
|
29671
|
-
}
|
|
29672
|
-
// 如果已经初始化且不强制重新初始化,返回之前保存的初始化信息
|
|
29673
|
-
if (this.isInitialized && !forceReinit) {
|
|
29674
|
-
if (this.debug) {
|
|
29675
|
-
console.warn('CustomerSDK already initialized, returning cached result. Use forceReinit=true to reinitialize.');
|
|
29676
|
-
}
|
|
29677
|
-
if (this.initResult) {
|
|
29678
|
-
return this.initResult;
|
|
29679
|
-
}
|
|
29680
|
-
throw new Error('SDK already initialized but cannot retrieve initialization info');
|
|
29681
|
-
}
|
|
29682
|
-
// 设置初始化锁
|
|
29683
|
-
this.isInitializing = true;
|
|
29684
|
-
// 如果需要强制重新初始化,先清理旧资源
|
|
29685
|
-
if (this.isInitialized && forceReinit) {
|
|
29686
|
-
if (this.debug) {
|
|
29687
|
-
console.log('Force reinitializing SDK...');
|
|
29688
|
-
}
|
|
29689
|
-
// 清理旧的截图管理器
|
|
29690
|
-
this.screenshotManager?.destroy();
|
|
29691
|
-
this.screenshotManager = null;
|
|
29692
|
-
// 注意:图标管理器暂时保留,稍后检查配置是否变化再决定是否重新创建
|
|
29693
|
-
// 重置初始化标志
|
|
29694
|
-
this.isInitialized = false;
|
|
29695
|
-
}
|
|
29696
|
-
this.config = config;
|
|
29697
|
-
this.debug = config.debug ?? false;
|
|
29698
|
-
try {
|
|
29699
|
-
// 获取设备指纹ID
|
|
29700
|
-
const rawDeviceId = await this.getDeviceId();
|
|
29701
|
-
if (this.debug) {
|
|
29702
|
-
console.log('Raw Device ID:', rawDeviceId);
|
|
29703
|
-
}
|
|
29704
|
-
// 计算返回给前端的 deviceId:md5(deviceId + getReferrer())
|
|
29705
|
-
const referrer = this.getReferrer(config);
|
|
29706
|
-
const deviceId = cryptoJsExports.MD5(rawDeviceId + referrer).toString();
|
|
29707
|
-
if (this.debug) {
|
|
29708
|
-
console.log('Raw Device ID:', rawDeviceId);
|
|
29709
|
-
console.log('MD5 Device ID (for frontend):', deviceId);
|
|
29710
|
-
console.log('Referrer used:', referrer);
|
|
29711
|
-
}
|
|
29712
|
-
// 准备返回的初始化信息(返回给前端的是 md5 后的 deviceId)
|
|
29713
|
-
const initResult = {
|
|
29714
|
-
deviceId,
|
|
29715
|
-
referrer,
|
|
29716
|
-
agent: config.agent,
|
|
29717
|
-
timestamp: Date.now()
|
|
29718
|
-
};
|
|
29719
|
-
// 处理图标管理器(优化:如果配置没变化,保留图标避免闪烁)
|
|
29720
|
-
// target 和 iconPosition 只从 config 读取
|
|
29721
|
-
const iconPosition = config.iconPosition ?? this.lastIconConfig?.position;
|
|
29722
|
-
const iconTarget = config.target ?? this.lastIconConfig?.target;
|
|
29723
|
-
// 检查图标配置是否变化
|
|
29724
|
-
const iconConfigChanged = this.isIconConfigChanged(iconPosition, iconTarget);
|
|
29725
|
-
if (iconConfigChanged) {
|
|
29726
|
-
// 配置变化了,需要重新创建图标管理器
|
|
29727
|
-
if (this.iconManager) {
|
|
29728
|
-
this.iconManager.hide();
|
|
29729
|
-
this.iconManager = null; // 先清空引用,避免引用混乱
|
|
29730
|
-
if (this.debug) {
|
|
29731
|
-
console.log('Icon config changed, recreating icon manager');
|
|
29732
|
-
}
|
|
29733
|
-
}
|
|
29734
|
-
this.iconManager = new IconManager(iconPosition, this.debug, iconTarget, {
|
|
29735
|
-
sideAttach: config.sideAttach ?? true,
|
|
29736
|
-
sideHideRatio: config.sideHideRatio ?? 0.5,
|
|
29737
|
-
magnetic: config.magnetic ?? true,
|
|
29738
|
-
magneticDirection: config.magneticDirection ?? 'x',
|
|
29739
|
-
margin: config.margin ?? 10,
|
|
29740
|
-
autoAttachDelay: config.autoAttachDelay ?? 3000
|
|
29741
|
-
});
|
|
29742
|
-
await this.iconManager.show();
|
|
29743
|
-
// 保存新的配置
|
|
29744
|
-
this.lastIconConfig = { position: iconPosition, target: iconTarget };
|
|
29745
|
-
}
|
|
29746
|
-
else {
|
|
29747
|
-
// 配置没变化,保留图标管理器(避免闪烁)
|
|
29748
|
-
if (!this.iconManager) {
|
|
29749
|
-
// 如果不存在,创建新的
|
|
29750
|
-
this.iconManager = new IconManager(iconPosition, this.debug, iconTarget, {
|
|
29751
|
-
sideAttach: config.sideAttach ?? true,
|
|
29752
|
-
sideHideRatio: config.sideHideRatio ?? 0.5,
|
|
29753
|
-
magnetic: config.magnetic ?? true,
|
|
29754
|
-
magneticDirection: config.magneticDirection ?? 'x',
|
|
29755
|
-
margin: config.margin ?? 10,
|
|
29756
|
-
autoAttachDelay: config.autoAttachDelay ?? 3000
|
|
29757
|
-
});
|
|
29758
|
-
await this.iconManager.show();
|
|
29759
|
-
}
|
|
29760
|
-
else {
|
|
29761
|
-
// 已存在,确保显示(可能被隐藏了)
|
|
29762
|
-
await this.iconManager.show();
|
|
29763
|
-
if (this.debug) {
|
|
29764
|
-
console.log('Icon config unchanged, keeping existing icon manager');
|
|
29765
|
-
}
|
|
29766
|
-
}
|
|
29767
|
-
// 更新配置记录
|
|
29768
|
-
this.lastIconConfig = { position: iconPosition, target: iconTarget };
|
|
29769
|
-
}
|
|
29770
|
-
// 设置点击事件:图标点击回调(由外部处理)
|
|
29771
|
-
this.iconManager.onClick(() => {
|
|
29772
|
-
// 图标点击事件由外部处理(例如打开弹窗)
|
|
29773
|
-
// 这里只清除通知
|
|
29774
|
-
this.clearNotification();
|
|
29775
|
-
});
|
|
29776
|
-
// 初始化截图管理器(如果启用了截图功能)
|
|
29777
|
-
if (config.screenshot) {
|
|
29778
|
-
// 默认截图目标为 document.body,可以通过配置自定义
|
|
29779
|
-
const targetElement = document.body;
|
|
29780
|
-
// 传入发送消息到 iframe 的回调函数
|
|
29781
|
-
// 将 debug 配置传递给截图管理器
|
|
29782
|
-
const screenshotOptions = {
|
|
29783
|
-
...config.screenshot,
|
|
29784
|
-
debug: this.debug // 直接传递 debug 标志
|
|
29785
|
-
};
|
|
29786
|
-
// 检查 options 是否包含 sendData 回调(ScreenshotMessageCallback)
|
|
29787
|
-
const sendToExternal = options && 'sendData' in options ? options.sendData : undefined;
|
|
29788
|
-
if (this.debug) {
|
|
29789
|
-
console.log('[CustomerServiceSDK] 初始化截图管理器:');
|
|
29790
|
-
console.log(' options:', options ? '存在' : 'null/undefined', options);
|
|
29791
|
-
console.log(' sendData:', sendToExternal ? '存在' : 'undefined', typeof sendToExternal);
|
|
29792
|
-
}
|
|
29793
|
-
this.screenshotManager = new ScreenshotManager(targetElement, screenshotOptions, sendToExternal);
|
|
29794
|
-
// 自动启用截图功能(用于测试,实际使用时需要通过 iframe 消息启用)
|
|
29795
|
-
this.screenshotManager.enable(true);
|
|
29796
|
-
if (this.debug) {
|
|
29797
|
-
console.log('CustomerSDK screenshot manager initialized and enabled');
|
|
29798
|
-
}
|
|
29799
|
-
}
|
|
29800
|
-
this.isInitialized = true;
|
|
29801
|
-
// 保存初始化结果,以便后续获取
|
|
29802
|
-
this.initResult = initResult;
|
|
29803
|
-
if (this.debug) {
|
|
29804
|
-
console.log('CustomerSDK initialized successfully (icon + screenshot only)');
|
|
29805
|
-
}
|
|
29806
|
-
// 返回初始化信息
|
|
29807
|
-
return initResult;
|
|
29808
|
-
}
|
|
29809
|
-
catch (error) {
|
|
29810
|
-
// 错误始终输出
|
|
29811
|
-
console.error('Failed to initialize CustomerSDK:', error);
|
|
29812
|
-
// 清理已创建的资源(防止资源泄漏)
|
|
29813
|
-
try {
|
|
29814
|
-
if (this.iconManager) {
|
|
29815
|
-
this.iconManager.hide();
|
|
29816
|
-
this.iconManager = null;
|
|
29817
|
-
}
|
|
29818
|
-
if (this.screenshotManager) {
|
|
29819
|
-
this.screenshotManager.destroy();
|
|
29820
|
-
this.screenshotManager = null;
|
|
29821
|
-
}
|
|
29822
|
-
this.isInitialized = false;
|
|
29823
|
-
this.initResult = null;
|
|
29824
|
-
}
|
|
29825
|
-
catch (cleanupError) {
|
|
29826
|
-
// 清理过程中的错误不应该影响原始错误的抛出
|
|
29827
|
-
console.error('Error during cleanup after initialization failure:', cleanupError);
|
|
29828
|
-
}
|
|
29829
|
-
throw error;
|
|
29830
|
-
}
|
|
29831
|
-
finally {
|
|
29832
|
-
// 释放初始化锁
|
|
29833
|
-
this.isInitializing = false;
|
|
29834
|
-
}
|
|
29835
|
-
}
|
|
29836
|
-
/**
|
|
29837
|
-
* 显示/隐藏悬浮图标
|
|
29838
|
-
*/
|
|
29839
|
-
showIcon() {
|
|
29840
|
-
this.iconManager?.show();
|
|
29841
|
-
}
|
|
29842
|
-
hideIcon() {
|
|
29843
|
-
this.iconManager?.hide();
|
|
29844
|
-
}
|
|
29845
|
-
/**
|
|
29846
|
-
* 设置图标位置
|
|
29847
|
-
*/
|
|
29848
|
-
setIconPosition(position) {
|
|
29849
|
-
this.iconManager?.setPosition(position);
|
|
29850
|
-
}
|
|
29851
|
-
/**
|
|
29852
|
-
* 设置图标坐标位置(x, y)
|
|
29853
|
-
*/
|
|
29854
|
-
setIconCoordinates(position) {
|
|
29855
|
-
this.iconManager?.setIconPosition(position);
|
|
29856
|
-
}
|
|
29857
|
-
/**
|
|
29858
|
-
* 更新图标样式
|
|
29859
|
-
*/
|
|
29860
|
-
setIconStyle(style) {
|
|
29861
|
-
this.iconManager?.setStyle(style);
|
|
29862
|
-
}
|
|
29863
|
-
/**
|
|
29864
|
-
* 设置图标点击回调
|
|
29865
|
-
*/
|
|
29866
|
-
onIconClick(callback) {
|
|
29867
|
-
this.iconManager?.onClick(callback);
|
|
29868
|
-
}
|
|
29869
|
-
/**
|
|
29870
|
-
* 获取连接状态
|
|
29871
|
-
* 注意:真正的连接状态保存在iframe中的SSE连接中
|
|
29872
|
-
*/
|
|
29873
|
-
getConnectionStatus() {
|
|
29874
|
-
return this.isInitialized;
|
|
29875
|
-
}
|
|
29876
|
-
/**
|
|
29877
|
-
* 显示消息通知
|
|
29878
|
-
*/
|
|
29879
|
-
showNotification(badgeCount = 1, options = {}) {
|
|
29880
|
-
if (!this.iconManager) {
|
|
29881
|
-
if (this.debug) {
|
|
29882
|
-
console.warn('SDK not initialized');
|
|
29883
|
-
}
|
|
29884
|
-
return;
|
|
29885
|
-
}
|
|
29886
|
-
this.iconManager.showNotification({
|
|
29887
|
-
badgeCount: typeof badgeCount === 'string' ? 0 : badgeCount,
|
|
29888
|
-
badgeText: typeof badgeCount === 'string' ? badgeCount : '',
|
|
29889
|
-
pulse: options.pulse || false
|
|
29890
|
-
});
|
|
29891
|
-
// 自动隐藏通知
|
|
29892
|
-
if (options.autoHide && options.autoHide > 0) {
|
|
29893
|
-
setTimeout(() => {
|
|
29894
|
-
this.iconManager?.clearNotification();
|
|
29895
|
-
}, options.autoHide);
|
|
29896
|
-
}
|
|
29897
|
-
}
|
|
29898
|
-
/**
|
|
29899
|
-
* 清除消息通知
|
|
29900
|
-
*/
|
|
29901
|
-
clearNotification() {
|
|
29902
|
-
this.iconManager?.clearNotification();
|
|
29903
|
-
}
|
|
29904
|
-
/**
|
|
29905
|
-
* 设置截图目标元素
|
|
29906
|
-
*/
|
|
29907
|
-
setScreenshotTarget(element) {
|
|
29908
|
-
this.screenshotManager?.setTargetElement(element);
|
|
29909
|
-
}
|
|
29910
|
-
/**
|
|
29911
|
-
* 手动触发截图
|
|
29912
|
-
*/
|
|
29913
|
-
async captureScreenshot(force = false) {
|
|
29914
|
-
if (!this.screenshotManager) {
|
|
29915
|
-
if (this.debug) {
|
|
29916
|
-
console.warn('截图功能未启用');
|
|
29917
|
-
}
|
|
29918
|
-
return false;
|
|
29919
|
-
}
|
|
29920
|
-
return await this.screenshotManager.captureOnce(force);
|
|
29921
|
-
}
|
|
29922
|
-
/**
|
|
29923
|
-
* 启用/禁用截图功能
|
|
29924
|
-
*/
|
|
29925
|
-
enableScreenshot(enabled) {
|
|
29926
|
-
if (!this.screenshotManager) {
|
|
29927
|
-
if (this.debug) {
|
|
29928
|
-
console.warn('截图管理器未初始化');
|
|
29929
|
-
}
|
|
29930
|
-
return;
|
|
29931
|
-
}
|
|
29932
|
-
this.screenshotManager.enable(enabled);
|
|
29933
|
-
if (this.debug) {
|
|
29934
|
-
console.log(`📸 截图功能已${enabled ? '启用' : '禁用'}`);
|
|
29935
|
-
}
|
|
29936
|
-
}
|
|
29937
|
-
/**
|
|
29938
|
-
* 获取截图状态
|
|
29939
|
-
*/
|
|
29940
|
-
getScreenshotState() {
|
|
29941
|
-
return this.screenshotManager?.getState() || null;
|
|
29942
|
-
}
|
|
29943
|
-
/**
|
|
29944
|
-
* 更新截图配置(动态更新,无需重新初始化)
|
|
29945
|
-
* @param options 要更新的配置项(部分更新)
|
|
29946
|
-
*/
|
|
29947
|
-
updateScreenshotOptions(options) {
|
|
29948
|
-
if (!this.screenshotManager) {
|
|
29949
|
-
if (this.debug) {
|
|
29950
|
-
console.warn('截图管理器未初始化,无法更新配置');
|
|
29951
|
-
}
|
|
29952
|
-
return;
|
|
29953
|
-
}
|
|
29954
|
-
this.screenshotManager.updateOptions(options);
|
|
29955
|
-
if (this.debug) {
|
|
29956
|
-
console.log('📸 截图配置已更新:', options);
|
|
29957
|
-
}
|
|
29958
|
-
}
|
|
29959
|
-
/**
|
|
29960
|
-
* 触发截图配置(用于弹窗组件场景,替代之前的 iframe postMessage)
|
|
29961
|
-
* @param configJson 截图配置的 JSON 字符串(BinaryConfig 格式)
|
|
29962
|
-
*/
|
|
29963
|
-
triggerScreenshotConfig(configJson) {
|
|
29964
|
-
if (!this.screenshotManager) {
|
|
29965
|
-
if (this.debug) {
|
|
29966
|
-
console.warn('[CustomerServiceSDK] ScreenshotManager not initialized');
|
|
29967
|
-
}
|
|
29968
|
-
return;
|
|
29969
|
-
}
|
|
29970
|
-
this.screenshotManager.handleScreenshotConfig(configJson);
|
|
29971
|
-
if (this.debug) {
|
|
29972
|
-
console.log('[CustomerServiceSDK] Screenshot config triggered:', configJson);
|
|
29973
|
-
}
|
|
29974
|
-
}
|
|
29975
|
-
/**
|
|
29976
|
-
* 销毁 SDK
|
|
29977
|
-
*/
|
|
29978
|
-
destroy() {
|
|
29979
|
-
this.iconManager?.hide();
|
|
29980
|
-
this.screenshotManager?.destroy();
|
|
29981
|
-
this.iconManager = null;
|
|
29982
|
-
this.screenshotManager = null;
|
|
29983
|
-
this.config = null;
|
|
29984
|
-
this.initResult = null;
|
|
29985
|
-
this.lastIconConfig = null;
|
|
29986
|
-
this.isInitialized = false;
|
|
29987
|
-
if (this.debug) {
|
|
29988
|
-
console.log('CustomerSDK destroyed');
|
|
29989
|
-
}
|
|
29990
|
-
}
|
|
29991
|
-
/**
|
|
29992
|
-
* 获取初始化信息(设备ID等)
|
|
29993
|
-
* 如果已初始化,返回保存的结果;否则返回 null
|
|
29994
|
-
*/
|
|
29995
|
-
getInitResult() {
|
|
29996
|
-
return this.initResult;
|
|
29997
|
-
}
|
|
29998
|
-
/**
|
|
29999
|
-
* 生成初始化信息(设备ID等)
|
|
30000
|
-
* 可以在任何时候调用,即使没有初始化也能获取 deviceId 等信息
|
|
30001
|
-
* @param agent 代理商ID(可选,如果不传则从已保存的配置中获取)
|
|
30002
|
-
* @returns 返回初始化信息(包含设备ID等)
|
|
30003
|
-
*/
|
|
30004
|
-
async generateInitResult(agent) {
|
|
30005
|
-
// 获取设备指纹ID
|
|
30006
|
-
const rawDeviceId = await this.getDeviceId();
|
|
30007
|
-
// 获取 referrer(优先使用已保存的配置,否则使用当前页面的 referrer)
|
|
30008
|
-
const referrer = this.config?.referrer || this.getReferrer(this.config || {});
|
|
30009
|
-
// 计算返回给前端的 deviceId:md5(deviceId + getReferrer())
|
|
30010
|
-
const deviceId = cryptoJsExports.MD5(rawDeviceId + referrer).toString();
|
|
30011
|
-
// 使用传入的 agent 或已保存的配置中的 agent
|
|
30012
|
-
const finalAgent = agent || this.config?.agent;
|
|
30013
|
-
if (this.debug) {
|
|
30014
|
-
console.log('Generated InitResult:', {
|
|
30015
|
-
deviceId,
|
|
30016
|
-
referrer,
|
|
30017
|
-
agent: finalAgent,
|
|
30018
|
-
timestamp: Date.now()
|
|
30019
|
-
});
|
|
30020
|
-
}
|
|
30021
|
-
return {
|
|
30022
|
-
deviceId,
|
|
30023
|
-
referrer,
|
|
30024
|
-
agent: finalAgent,
|
|
30025
|
-
timestamp: Date.now()
|
|
30026
|
-
};
|
|
30027
|
-
}
|
|
30028
|
-
/**
|
|
30029
|
-
* 获取设备指纹ID
|
|
30030
|
-
*/
|
|
30031
|
-
async getDeviceId() {
|
|
30032
|
-
if (this.debug) {
|
|
30033
|
-
console.log('🔍 Starting to get device fingerprint...');
|
|
30034
|
-
}
|
|
30035
|
-
try {
|
|
30036
|
-
if (this.debug) {
|
|
30037
|
-
console.log('📦 Loading FingerprintJS...');
|
|
30038
|
-
}
|
|
30039
|
-
const fp = await index$1.load();
|
|
30040
|
-
if (this.debug) {
|
|
30041
|
-
console.log('🎯 Getting device fingerprint...');
|
|
30042
|
-
}
|
|
30043
|
-
const result = await fp.get();
|
|
30044
|
-
if (this.debug) {
|
|
30045
|
-
console.log('✅ FingerprintJS result:', result);
|
|
30046
|
-
console.log('🆔 Device ID obtained:', result.visitorId);
|
|
30047
|
-
}
|
|
30048
|
-
return result.visitorId;
|
|
30049
|
-
}
|
|
30050
|
-
catch (error) {
|
|
30051
|
-
if (this.debug) {
|
|
30052
|
-
console.warn('❌ Failed to get device fingerprint, using fallback:', error);
|
|
30053
|
-
}
|
|
30054
|
-
const fallbackId = 'device_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
|
|
30055
|
-
if (this.debug) {
|
|
30056
|
-
console.log('🆔 Fallback Device ID:', fallbackId);
|
|
30057
|
-
}
|
|
30058
|
-
return fallbackId;
|
|
30059
|
-
}
|
|
30060
|
-
}
|
|
30061
|
-
/**
|
|
30062
|
-
* 检查图标配置是否变化
|
|
30063
|
-
*/
|
|
30064
|
-
isIconConfigChanged(newPosition, newTarget) {
|
|
30065
|
-
// 如果没有保存的配置,说明是首次初始化,需要创建
|
|
30066
|
-
if (!this.lastIconConfig) {
|
|
30067
|
-
return true;
|
|
30068
|
-
}
|
|
30069
|
-
// 比较位置配置
|
|
30070
|
-
const positionChanged = JSON.stringify(this.lastIconConfig.position) !== JSON.stringify(newPosition);
|
|
30071
|
-
// 比较 target 配置
|
|
30072
|
-
const oldTarget = this.lastIconConfig.target;
|
|
30073
|
-
let targetChanged = false;
|
|
30074
|
-
if (oldTarget !== newTarget) {
|
|
30075
|
-
// 如果引用不同,进一步检查
|
|
30076
|
-
if (typeof oldTarget === 'string' && typeof newTarget === 'string') {
|
|
30077
|
-
// 都是字符串,比较值
|
|
30078
|
-
targetChanged = oldTarget !== newTarget;
|
|
30079
|
-
}
|
|
30080
|
-
else if (oldTarget instanceof HTMLElement && newTarget instanceof HTMLElement) {
|
|
30081
|
-
// 都是 HTMLElement,比较引用(引用不同就是变化了)
|
|
30082
|
-
targetChanged = true;
|
|
30083
|
-
}
|
|
30084
|
-
else {
|
|
30085
|
-
// 类型不同,肯定是变化了
|
|
30086
|
-
targetChanged = true;
|
|
30087
|
-
}
|
|
30088
|
-
}
|
|
30089
|
-
return positionChanged || targetChanged;
|
|
30090
|
-
}
|
|
30091
|
-
/**
|
|
30092
|
-
* 获取 referrer(统一获取逻辑)
|
|
30093
|
-
*/
|
|
30094
|
-
getReferrer(config) {
|
|
30095
|
-
return config.referrer || document.referrer || document.location.href;
|
|
30096
|
-
}
|
|
30097
|
-
}
|
|
30098
|
-
// 创建全局实例
|
|
30099
29647
|
let globalSDKInstance = null;
|
|
30100
29648
|
/**
|
|
30101
|
-
*
|
|
30102
|
-
* @param config SDK配置
|
|
30103
|
-
* @param options UI选项 或 截图回调(可选)
|
|
30104
|
-
* @param forceReinit 是否强制重新初始化(用于更新token等配置)
|
|
30105
|
-
* @returns 返回初始化信息(包含设备ID等)
|
|
29649
|
+
* 获取全局 SDK 实例(懒加载)
|
|
30106
29650
|
*/
|
|
30107
|
-
|
|
29651
|
+
function getSDKInstance() {
|
|
30108
29652
|
if (!globalSDKInstance) {
|
|
30109
|
-
globalSDKInstance = new
|
|
29653
|
+
globalSDKInstance = new CustomerSDK$1();
|
|
30110
29654
|
}
|
|
30111
|
-
return
|
|
30112
|
-
}
|
|
29655
|
+
return globalSDKInstance;
|
|
29656
|
+
}
|
|
30113
29657
|
/**
|
|
30114
|
-
*
|
|
29658
|
+
* 全局初始化函数
|
|
29659
|
+
* @param config SDK配置
|
|
29660
|
+
* @param screenshotCallback 截图消息回调(可选)
|
|
29661
|
+
* @param initCallback 初始化回调(可选,包含图标点击回调等)
|
|
29662
|
+
* @returns 返回初始化信息(包含设备ID等)
|
|
30115
29663
|
*/
|
|
30116
|
-
const
|
|
30117
|
-
|
|
30118
|
-
|
|
30119
|
-
}
|
|
30120
|
-
return globalSDKInstance;
|
|
29664
|
+
const init = async (config, screenshotCallback, initCallback) => {
|
|
29665
|
+
const sdk = getSDKInstance();
|
|
29666
|
+
return await sdk.init(config, screenshotCallback, initCallback);
|
|
30121
29667
|
};
|
|
30122
29668
|
/**
|
|
30123
|
-
*
|
|
29669
|
+
* 显示悬浮图标
|
|
30124
29670
|
*/
|
|
30125
29671
|
const showIcon = () => {
|
|
30126
|
-
|
|
30127
|
-
sdk.showIcon();
|
|
29672
|
+
getSDKInstance().showIcon();
|
|
30128
29673
|
};
|
|
29674
|
+
/**
|
|
29675
|
+
* 隐藏悬浮图标
|
|
29676
|
+
*/
|
|
30129
29677
|
const hideIcon = () => {
|
|
30130
|
-
|
|
30131
|
-
sdk.hideIcon();
|
|
29678
|
+
getSDKInstance().hideIcon();
|
|
30132
29679
|
};
|
|
29680
|
+
/**
|
|
29681
|
+
* 设置图标位置(预设位置)
|
|
29682
|
+
*/
|
|
30133
29683
|
const setIconPosition = (position) => {
|
|
30134
|
-
|
|
30135
|
-
sdk.setIconPosition(position);
|
|
29684
|
+
getSDKInstance().setIconPosition(position);
|
|
30136
29685
|
};
|
|
29686
|
+
/**
|
|
29687
|
+
* 设置图标坐标位置(自定义坐标)
|
|
29688
|
+
*/
|
|
30137
29689
|
const setIconCoordinates = (position) => {
|
|
30138
|
-
|
|
30139
|
-
sdk.setIconCoordinates(position);
|
|
29690
|
+
getSDKInstance().setIconCoordinates(position);
|
|
30140
29691
|
};
|
|
29692
|
+
/**
|
|
29693
|
+
* 更新图标样式
|
|
29694
|
+
*/
|
|
30141
29695
|
const setIconStyle = (style) => {
|
|
30142
|
-
|
|
30143
|
-
sdk.setIconStyle(style);
|
|
29696
|
+
getSDKInstance().setIconStyle(style);
|
|
30144
29697
|
};
|
|
30145
29698
|
/**
|
|
30146
29699
|
* 设置图标点击回调
|
|
30147
29700
|
*/
|
|
30148
29701
|
const onIconClick = (callback) => {
|
|
30149
|
-
|
|
30150
|
-
sdk.onIconClick(callback);
|
|
29702
|
+
getSDKInstance().onIconClick(callback);
|
|
30151
29703
|
};
|
|
30152
29704
|
/**
|
|
30153
|
-
*
|
|
29705
|
+
* 设置图标的 HTML 内容
|
|
30154
29706
|
*/
|
|
30155
|
-
const
|
|
30156
|
-
|
|
30157
|
-
return sdk.getConnectionStatus();
|
|
29707
|
+
const setIconHTML = (html) => {
|
|
29708
|
+
getSDKInstance().setIconHTML(html);
|
|
30158
29709
|
};
|
|
30159
29710
|
/**
|
|
30160
|
-
*
|
|
29711
|
+
* 设置图标的图片 URL
|
|
30161
29712
|
*/
|
|
30162
|
-
const
|
|
30163
|
-
|
|
30164
|
-
return sdk.getInitResult();
|
|
29713
|
+
const setIconImage = (imageUrl) => {
|
|
29714
|
+
getSDKInstance().setIconImage(imageUrl);
|
|
30165
29715
|
};
|
|
30166
29716
|
/**
|
|
30167
|
-
*
|
|
30168
|
-
* 可以在任何时候调用,即使没有初始化也能获取 deviceId 等信息
|
|
30169
|
-
* @param agent 代理商ID(可选,如果不传则从已保存的配置中获取)
|
|
30170
|
-
* @returns 返回初始化信息(包含设备ID等)
|
|
29717
|
+
* 显示图标通知(红点)
|
|
30171
29718
|
*/
|
|
30172
|
-
const
|
|
30173
|
-
|
|
30174
|
-
return await sdk.generateInitResult(agent);
|
|
29719
|
+
const showNotification = (options) => {
|
|
29720
|
+
getSDKInstance().showNotification(options);
|
|
30175
29721
|
};
|
|
30176
29722
|
/**
|
|
30177
|
-
*
|
|
29723
|
+
* 清除图标通知
|
|
30178
29724
|
*/
|
|
30179
|
-
const showNotification = (badgeCount = 1, options = {}) => {
|
|
30180
|
-
const sdk = getInstance();
|
|
30181
|
-
sdk.showNotification(badgeCount, options);
|
|
30182
|
-
};
|
|
30183
29725
|
const clearNotification = () => {
|
|
30184
|
-
|
|
30185
|
-
sdk.clearNotification();
|
|
29726
|
+
getSDKInstance().clearNotification();
|
|
30186
29727
|
};
|
|
29728
|
+
/**
|
|
29729
|
+
* 手动触发截图配置(用于测试)
|
|
29730
|
+
* @param configJson BinaryConfig 的 JSON 字符串
|
|
29731
|
+
*/
|
|
29732
|
+
const triggerScreenshotConfig = (configJson) => {
|
|
29733
|
+
getSDKInstance().triggerScreenshotConfig(configJson);
|
|
29734
|
+
};
|
|
29735
|
+
/**
|
|
29736
|
+
* 销毁 SDK(清理所有资源)
|
|
29737
|
+
*/
|
|
30187
29738
|
const destroy = () => {
|
|
30188
|
-
|
|
30189
|
-
sdk.destroy();
|
|
29739
|
+
getSDKInstance().destroy();
|
|
30190
29740
|
globalSDKInstance = null;
|
|
30191
29741
|
};
|
|
30192
29742
|
/**
|
|
30193
|
-
*
|
|
29743
|
+
* 获取当前设备ID(md5后的)
|
|
30194
29744
|
*/
|
|
30195
|
-
const
|
|
30196
|
-
|
|
30197
|
-
sdk.setScreenshotTarget(element);
|
|
30198
|
-
};
|
|
30199
|
-
const captureScreenshot = async (force = false) => {
|
|
30200
|
-
const sdk = getInstance();
|
|
30201
|
-
return await sdk.captureScreenshot(force);
|
|
30202
|
-
};
|
|
30203
|
-
const enableScreenshot = (enabled) => {
|
|
30204
|
-
const sdk = getInstance();
|
|
30205
|
-
sdk.enableScreenshot(enabled);
|
|
30206
|
-
};
|
|
30207
|
-
const getScreenshotState = () => {
|
|
30208
|
-
const sdk = getInstance();
|
|
30209
|
-
return sdk.getScreenshotState();
|
|
30210
|
-
};
|
|
30211
|
-
const updateScreenshotOptions = (options) => {
|
|
30212
|
-
const sdk = getInstance();
|
|
30213
|
-
sdk.updateScreenshotOptions(options);
|
|
29745
|
+
const getDeviceId = () => {
|
|
29746
|
+
return getSDKInstance().getDeviceId();
|
|
30214
29747
|
};
|
|
30215
29748
|
/**
|
|
30216
|
-
*
|
|
30217
|
-
* @param configJson 截图配置的 JSON 字符串(BinaryConfig 格式)
|
|
29749
|
+
* 获取 SDK 实例(用于高级用法)
|
|
30218
29750
|
*/
|
|
30219
|
-
const
|
|
30220
|
-
|
|
30221
|
-
sdk.triggerScreenshotConfig(configJson);
|
|
29751
|
+
const getInstance = () => {
|
|
29752
|
+
return getSDKInstance();
|
|
30222
29753
|
};
|
|
30223
|
-
|
|
29754
|
+
/**
|
|
29755
|
+
* 导出 CustomerSDK 类(用于创建多个实例)
|
|
29756
|
+
*/
|
|
29757
|
+
const CustomerSDK = CustomerSDK$1;
|
|
29758
|
+
/**
|
|
29759
|
+
* 默认导出(兼容旧版用法)
|
|
29760
|
+
*/
|
|
30224
29761
|
var index = {
|
|
30225
29762
|
init,
|
|
30226
|
-
getInstance,
|
|
30227
|
-
getInitResult,
|
|
30228
|
-
generateInitResult,
|
|
30229
29763
|
showIcon,
|
|
30230
29764
|
hideIcon,
|
|
30231
29765
|
setIconPosition,
|
|
30232
29766
|
setIconCoordinates,
|
|
30233
29767
|
setIconStyle,
|
|
30234
29768
|
onIconClick,
|
|
30235
|
-
|
|
29769
|
+
setIconHTML,
|
|
29770
|
+
setIconImage,
|
|
30236
29771
|
showNotification,
|
|
30237
29772
|
clearNotification,
|
|
30238
|
-
setScreenshotTarget,
|
|
30239
|
-
captureScreenshot,
|
|
30240
|
-
enableScreenshot,
|
|
30241
|
-
getScreenshotState,
|
|
30242
|
-
updateScreenshotOptions,
|
|
30243
29773
|
triggerScreenshotConfig,
|
|
30244
|
-
destroy
|
|
29774
|
+
destroy,
|
|
29775
|
+
getDeviceId,
|
|
29776
|
+
getInstance,
|
|
29777
|
+
CustomerSDK
|
|
30245
29778
|
};
|
|
30246
29779
|
|
|
30247
29780
|
exports.CustomerSDK = CustomerSDK;
|
|
30248
|
-
exports.CustomerServiceSDK = CustomerServiceSDK;
|
|
30249
|
-
exports.captureScreenshot = captureScreenshot;
|
|
30250
29781
|
exports.clearNotification = clearNotification;
|
|
30251
29782
|
exports.default = index;
|
|
30252
29783
|
exports.destroy = destroy;
|
|
30253
|
-
exports.
|
|
30254
|
-
exports.generateInitResult = generateInitResult;
|
|
30255
|
-
exports.getConnectionStatus = getConnectionStatus;
|
|
30256
|
-
exports.getInitResult = getInitResult;
|
|
29784
|
+
exports.getDeviceId = getDeviceId;
|
|
30257
29785
|
exports.getInstance = getInstance;
|
|
30258
|
-
exports.getScreenshotState = getScreenshotState;
|
|
30259
29786
|
exports.hideIcon = hideIcon;
|
|
30260
29787
|
exports.init = init;
|
|
30261
29788
|
exports.onIconClick = onIconClick;
|
|
30262
29789
|
exports.setIconCoordinates = setIconCoordinates;
|
|
29790
|
+
exports.setIconHTML = setIconHTML;
|
|
29791
|
+
exports.setIconImage = setIconImage;
|
|
30263
29792
|
exports.setIconPosition = setIconPosition;
|
|
30264
29793
|
exports.setIconStyle = setIconStyle;
|
|
30265
|
-
exports.setScreenshotTarget = setScreenshotTarget;
|
|
30266
29794
|
exports.showIcon = showIcon;
|
|
30267
29795
|
exports.showNotification = showNotification;
|
|
30268
29796
|
exports.triggerScreenshotConfig = triggerScreenshotConfig;
|
|
30269
|
-
exports.updateScreenshotOptions = updateScreenshotOptions;
|