customer-chat-sdk 1.0.46 → 1.0.48
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScreenshotManager.d.ts","sourceRoot":"","sources":["../../src/core/ScreenshotManager.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ScreenshotManager.d.ts","sourceRoot":"","sources":["../../src/core/ScreenshotManager.ts"],"names":[],"mappings":"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"}
|
package/dist/customer-sdk.cjs.js
CHANGED
|
@@ -14882,27 +14882,43 @@ class ScreenshotManager {
|
|
|
14882
14882
|
console.log(`📸 原始大小: ${Math.round(base64Data.length * 0.75 / 1024)} KB`);
|
|
14883
14883
|
console.log(`📸 Base64 长度: ${base64Data.length} 字符`);
|
|
14884
14884
|
}
|
|
14885
|
-
//
|
|
14886
|
-
const
|
|
14887
|
-
|
|
14888
|
-
|
|
14889
|
-
|
|
14890
|
-
|
|
14891
|
-
|
|
14892
|
-
|
|
14885
|
+
// 如果启用压缩(所有设备都支持)
|
|
14886
|
+
const shouldCompress = this.options.compress;
|
|
14887
|
+
if (shouldCompress) {
|
|
14888
|
+
// 确保 Worker 已创建
|
|
14889
|
+
if (!this.worker) {
|
|
14890
|
+
this.worker = this.createWorker();
|
|
14891
|
+
if (!this.options.silentMode) {
|
|
14892
|
+
if (this.worker) {
|
|
14893
|
+
console.log('📸 Worker 已创建,准备压缩');
|
|
14894
|
+
}
|
|
14895
|
+
else {
|
|
14896
|
+
console.warn('📸 ⚠️ Worker 创建失败,无法使用压缩功能');
|
|
14897
|
+
}
|
|
14898
|
+
}
|
|
14899
|
+
}
|
|
14900
|
+
if (this.worker) {
|
|
14901
|
+
if (!this.options.silentMode) {
|
|
14902
|
+
console.log('📸 发送到 WebWorker 进行压缩...');
|
|
14903
|
+
}
|
|
14904
|
+
this.worker.postMessage({
|
|
14905
|
+
type: 'COMPRESS_IMAGE',
|
|
14906
|
+
data: {
|
|
14907
|
+
dataUrl,
|
|
14908
|
+
maxWidth: this.options.maxWidth,
|
|
14909
|
+
maxHeight: this.options.maxHeight,
|
|
14910
|
+
quality: this.options.quality,
|
|
14911
|
+
outputFormat: this.options.outputFormat,
|
|
14912
|
+
timestamp,
|
|
14913
|
+
count: this.screenshotCount
|
|
14914
|
+
}
|
|
14915
|
+
});
|
|
14893
14916
|
}
|
|
14894
|
-
|
|
14895
|
-
|
|
14896
|
-
|
|
14897
|
-
dataUrl,
|
|
14898
|
-
maxWidth: this.options.maxWidth,
|
|
14899
|
-
maxHeight: this.options.maxHeight,
|
|
14900
|
-
quality: this.options.quality,
|
|
14901
|
-
outputFormat: this.options.outputFormat,
|
|
14902
|
-
timestamp,
|
|
14903
|
-
count: this.screenshotCount
|
|
14917
|
+
else {
|
|
14918
|
+
if (!this.options.silentMode) {
|
|
14919
|
+
console.warn('📸 ⚠️ Worker 不可用,跳过压缩(使用原始截图)');
|
|
14904
14920
|
}
|
|
14905
|
-
}
|
|
14921
|
+
}
|
|
14906
14922
|
}
|
|
14907
14923
|
this.error = null;
|
|
14908
14924
|
return true;
|
|
@@ -16697,25 +16713,219 @@ class ScreenshotManager {
|
|
|
16697
16713
|
return { width, height };
|
|
16698
16714
|
}
|
|
16699
16715
|
/**
|
|
16700
|
-
* 创建 WebWorker
|
|
16716
|
+
* 创建 WebWorker(实现类似 TinyPNG 的智能压缩)
|
|
16701
16717
|
*/
|
|
16702
16718
|
createWorker() {
|
|
16703
|
-
if (typeof Worker === 'undefined'
|
|
16719
|
+
if (typeof Worker === 'undefined') {
|
|
16704
16720
|
return null;
|
|
16705
16721
|
}
|
|
16706
16722
|
try {
|
|
16707
|
-
//
|
|
16723
|
+
// 完整的 Worker 压缩代码(类似 TinyPNG 的智能压缩)
|
|
16708
16724
|
const workerCode = `
|
|
16709
|
-
|
|
16725
|
+
// 图片压缩 Worker(类似 TinyPNG 的智能压缩)
|
|
16726
|
+
self.onmessage = async function(e) {
|
|
16710
16727
|
const { type, data } = e.data;
|
|
16728
|
+
|
|
16711
16729
|
if (type === 'COMPRESS_IMAGE') {
|
|
16712
|
-
|
|
16713
|
-
|
|
16714
|
-
|
|
16715
|
-
|
|
16716
|
-
|
|
16730
|
+
try {
|
|
16731
|
+
const { dataUrl, maxWidth, maxHeight, quality, outputFormat } = data;
|
|
16732
|
+
|
|
16733
|
+
// 1. 加载图片
|
|
16734
|
+
const img = await loadImage(dataUrl);
|
|
16735
|
+
|
|
16736
|
+
// 获取图片尺寸(ImageBitmap 或 Image 都支持)
|
|
16737
|
+
const imgWidth = img.width || img.naturalWidth || 0;
|
|
16738
|
+
const imgHeight = img.height || img.naturalHeight || 0;
|
|
16739
|
+
|
|
16740
|
+
if (imgWidth === 0 || imgHeight === 0) {
|
|
16741
|
+
throw new Error('无法获取图片尺寸');
|
|
16742
|
+
}
|
|
16743
|
+
|
|
16744
|
+
// 2. 计算压缩后的尺寸(保持宽高比)
|
|
16745
|
+
const { width, height } = calculateSize(
|
|
16746
|
+
imgWidth,
|
|
16747
|
+
imgHeight,
|
|
16748
|
+
maxWidth || 1600,
|
|
16749
|
+
maxHeight || 900
|
|
16750
|
+
);
|
|
16751
|
+
|
|
16752
|
+
// 3. 创建 OffscreenCanvas(Worker 中必须使用 OffscreenCanvas)
|
|
16753
|
+
if (typeof OffscreenCanvas === 'undefined') {
|
|
16754
|
+
throw new Error('浏览器不支持 OffscreenCanvas,无法在 Worker 中压缩');
|
|
16755
|
+
}
|
|
16756
|
+
|
|
16757
|
+
const canvas = new OffscreenCanvas(width, height);
|
|
16758
|
+
const ctx = canvas.getContext('2d');
|
|
16759
|
+
|
|
16760
|
+
if (!ctx) {
|
|
16761
|
+
throw new Error('无法获取 Canvas 上下文');
|
|
16762
|
+
}
|
|
16763
|
+
|
|
16764
|
+
// 4. 优化绘制设置(提升压缩质量)
|
|
16765
|
+
ctx.imageSmoothingEnabled = true;
|
|
16766
|
+
ctx.imageSmoothingQuality = 'high';
|
|
16767
|
+
|
|
16768
|
+
// 5. 使用白色背景(避免透明区域压缩问题)
|
|
16769
|
+
ctx.fillStyle = '#ffffff';
|
|
16770
|
+
ctx.fillRect(0, 0, width, height);
|
|
16771
|
+
|
|
16772
|
+
// 6. 绘制图片(高质量缩放)
|
|
16773
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
16774
|
+
|
|
16775
|
+
// 7. 转换为目标格式(智能质量调整)
|
|
16776
|
+
// OffscreenCanvas 使用 convertToBlob 而不是 toDataURL
|
|
16777
|
+
let compressedDataUrl;
|
|
16778
|
+
const finalQuality = Math.max(0.1, Math.min(0.95, quality || 0.15));
|
|
16779
|
+
|
|
16780
|
+
// 辅助函数:将 Blob 转换为 data URL
|
|
16781
|
+
async function blobToDataURL(blob) {
|
|
16782
|
+
return new Promise((resolve, reject) => {
|
|
16783
|
+
const reader = new FileReader();
|
|
16784
|
+
reader.onload = () => resolve(reader.result);
|
|
16785
|
+
reader.onerror = reject;
|
|
16786
|
+
reader.readAsDataURL(blob);
|
|
16787
|
+
});
|
|
16788
|
+
}
|
|
16789
|
+
|
|
16790
|
+
// 确定 MIME 类型
|
|
16791
|
+
let mimeType = 'image/png';
|
|
16792
|
+
if (outputFormat === 'webp') {
|
|
16793
|
+
mimeType = 'image/webp';
|
|
16794
|
+
} else if (outputFormat === 'jpeg') {
|
|
16795
|
+
mimeType = 'image/jpeg';
|
|
16796
|
+
}
|
|
16797
|
+
|
|
16798
|
+
// 第一次压缩
|
|
16799
|
+
let blob = await canvas.convertToBlob({
|
|
16800
|
+
type: mimeType,
|
|
16801
|
+
quality: finalQuality
|
|
16802
|
+
});
|
|
16803
|
+
|
|
16804
|
+
compressedDataUrl = await blobToDataURL(blob);
|
|
16805
|
+
|
|
16806
|
+
// 8. 如果压缩后文件仍然较大,尝试进一步降低质量
|
|
16807
|
+
const originalSize = dataUrl.length;
|
|
16808
|
+
let compressedSize = compressedDataUrl.length;
|
|
16809
|
+
|
|
16810
|
+
// 如果压缩后大小减少不足 20%,尝试更激进的压缩
|
|
16811
|
+
if (compressedSize > originalSize * 0.8 && finalQuality > 0.1 && (outputFormat === 'webp' || outputFormat === 'jpeg')) {
|
|
16812
|
+
const aggressiveQuality = Math.max(0.1, finalQuality * 0.7);
|
|
16813
|
+
|
|
16814
|
+
try {
|
|
16815
|
+
const moreCompressedBlob = await canvas.convertToBlob({
|
|
16816
|
+
type: mimeType,
|
|
16817
|
+
quality: aggressiveQuality
|
|
16818
|
+
});
|
|
16819
|
+
|
|
16820
|
+
const moreCompressedDataUrl = await blobToDataURL(moreCompressedBlob);
|
|
16821
|
+
|
|
16822
|
+
// 如果更激进的压缩效果更好,使用它
|
|
16823
|
+
if (moreCompressedDataUrl.length < compressedDataUrl.length) {
|
|
16824
|
+
compressedDataUrl = moreCompressedDataUrl;
|
|
16825
|
+
compressedSize = compressedDataUrl.length;
|
|
16826
|
+
}
|
|
16827
|
+
} catch (e) {
|
|
16828
|
+
// 忽略错误,使用之前的压缩结果
|
|
16829
|
+
}
|
|
16830
|
+
}
|
|
16831
|
+
|
|
16832
|
+
// 9. 返回压缩结果
|
|
16833
|
+
self.postMessage({
|
|
16834
|
+
type: 'SCREENSHOT_RESULT',
|
|
16835
|
+
data: {
|
|
16836
|
+
compressed: {
|
|
16837
|
+
dataUrl: compressedDataUrl,
|
|
16838
|
+
originalSize: originalSize,
|
|
16839
|
+
compressedSize: compressedDataUrl.length,
|
|
16840
|
+
compressionRatio: ((1 - compressedDataUrl.length / originalSize) * 100).toFixed(1)
|
|
16841
|
+
}
|
|
16842
|
+
}
|
|
16843
|
+
});
|
|
16844
|
+
} catch (error) {
|
|
16845
|
+
// 压缩失败,返回原始数据
|
|
16846
|
+
self.postMessage({
|
|
16847
|
+
type: 'SCREENSHOT_RESULT',
|
|
16848
|
+
data: {
|
|
16849
|
+
compressed: {
|
|
16850
|
+
dataUrl: data.dataUrl,
|
|
16851
|
+
error: error.message
|
|
16852
|
+
}
|
|
16853
|
+
}
|
|
16854
|
+
});
|
|
16855
|
+
}
|
|
16717
16856
|
}
|
|
16718
16857
|
};
|
|
16858
|
+
|
|
16859
|
+
// 加载图片的辅助函数(Worker 中使用 createImageBitmap)
|
|
16860
|
+
async function loadImage(dataUrl) {
|
|
16861
|
+
try {
|
|
16862
|
+
// 将 data URL 转换为 Blob
|
|
16863
|
+
let blob;
|
|
16864
|
+
if (typeof fetch !== 'undefined') {
|
|
16865
|
+
try {
|
|
16866
|
+
const response = await fetch(dataUrl);
|
|
16867
|
+
blob = await response.blob();
|
|
16868
|
+
} catch (e) {
|
|
16869
|
+
// fetch 失败,手动转换 data URL 到 Blob
|
|
16870
|
+
blob = dataURLToBlob(dataUrl);
|
|
16871
|
+
}
|
|
16872
|
+
} else {
|
|
16873
|
+
// 没有 fetch,手动转换
|
|
16874
|
+
blob = dataURLToBlob(dataUrl);
|
|
16875
|
+
}
|
|
16876
|
+
|
|
16877
|
+
// 使用 createImageBitmap 创建图片(Worker 中推荐方式)
|
|
16878
|
+
if (typeof createImageBitmap !== 'undefined') {
|
|
16879
|
+
return await createImageBitmap(blob);
|
|
16880
|
+
} else {
|
|
16881
|
+
// 回退方案:使用 Image(某些 Worker 环境可能支持)
|
|
16882
|
+
return new Promise((resolve, reject) => {
|
|
16883
|
+
const img = new Image();
|
|
16884
|
+
img.onload = () => resolve(img);
|
|
16885
|
+
img.onerror = reject;
|
|
16886
|
+
img.src = dataUrl;
|
|
16887
|
+
});
|
|
16888
|
+
}
|
|
16889
|
+
} catch (error) {
|
|
16890
|
+
// 如果 createImageBitmap 失败,尝试直接使用 Image
|
|
16891
|
+
return new Promise((resolve, reject) => {
|
|
16892
|
+
const img = new Image();
|
|
16893
|
+
img.onload = () => resolve(img);
|
|
16894
|
+
img.onerror = () => reject(error);
|
|
16895
|
+
img.src = dataUrl;
|
|
16896
|
+
});
|
|
16897
|
+
}
|
|
16898
|
+
}
|
|
16899
|
+
|
|
16900
|
+
// 将 data URL 转换为 Blob 的辅助函数
|
|
16901
|
+
function dataURLToBlob(dataUrl) {
|
|
16902
|
+
const arr = dataUrl.split(',');
|
|
16903
|
+
const mimeMatch = arr[0].match(/:(.*?);/);
|
|
16904
|
+
const mime = mimeMatch ? mimeMatch[1] : 'image/png';
|
|
16905
|
+
const bstr = atob(arr[1]);
|
|
16906
|
+
let n = bstr.length;
|
|
16907
|
+
const u8arr = new Uint8Array(n);
|
|
16908
|
+
while (n--) {
|
|
16909
|
+
u8arr[n] = bstr.charCodeAt(n);
|
|
16910
|
+
}
|
|
16911
|
+
return new Blob([u8arr], { type: mime });
|
|
16912
|
+
}
|
|
16913
|
+
|
|
16914
|
+
// 计算压缩后尺寸的辅助函数(保持宽高比)
|
|
16915
|
+
function calculateSize(originalWidth, originalHeight, maxWidth, maxHeight) {
|
|
16916
|
+
let width = originalWidth;
|
|
16917
|
+
let height = originalHeight;
|
|
16918
|
+
|
|
16919
|
+
if (width > maxWidth || height > maxHeight) {
|
|
16920
|
+
const widthRatio = maxWidth / width;
|
|
16921
|
+
const heightRatio = maxHeight / height;
|
|
16922
|
+
const ratio = Math.min(widthRatio, heightRatio);
|
|
16923
|
+
width = Math.round(width * ratio);
|
|
16924
|
+
height = Math.round(height * ratio);
|
|
16925
|
+
}
|
|
16926
|
+
|
|
16927
|
+
return { width, height };
|
|
16928
|
+
}
|
|
16719
16929
|
`;
|
|
16720
16930
|
const blob = new Blob([workerCode], { type: 'application/javascript' });
|
|
16721
16931
|
const workerUrl = URL.createObjectURL(blob);
|
|
@@ -16723,17 +16933,34 @@ class ScreenshotManager {
|
|
|
16723
16933
|
newWorker.onmessage = (e) => {
|
|
16724
16934
|
const { type, data } = e.data;
|
|
16725
16935
|
if (type === 'SCREENSHOT_RESULT' && data?.compressed) {
|
|
16936
|
+
const compressed = data.compressed;
|
|
16937
|
+
// 更新截图历史记录
|
|
16726
16938
|
if (this.screenshotHistory.length > 0) {
|
|
16727
|
-
this.screenshotHistory[this.screenshotHistory.length - 1] =
|
|
16939
|
+
this.screenshotHistory[this.screenshotHistory.length - 1] = compressed.dataUrl;
|
|
16940
|
+
// 打印压缩统计信息
|
|
16941
|
+
if (!this.options.silentMode && compressed.originalSize && compressed.compressedSize) {
|
|
16942
|
+
const originalKB = (compressed.originalSize * 0.75 / 1024).toFixed(2);
|
|
16943
|
+
const compressedKB = (compressed.compressedSize * 0.75 / 1024).toFixed(2);
|
|
16944
|
+
const ratio = compressed.compressionRatio || '0';
|
|
16945
|
+
console.log('📸 [Worker 压缩] ✅ 压缩完成');
|
|
16946
|
+
console.log(` 原始大小: ${originalKB} KB`);
|
|
16947
|
+
console.log(` 压缩后: ${compressedKB} KB`);
|
|
16948
|
+
console.log(` 压缩率: ${ratio}%`);
|
|
16949
|
+
if (compressed.error) {
|
|
16950
|
+
console.warn(` ⚠️ 压缩警告: ${compressed.error}`);
|
|
16951
|
+
}
|
|
16952
|
+
}
|
|
16728
16953
|
}
|
|
16729
16954
|
}
|
|
16730
16955
|
};
|
|
16731
16956
|
newWorker.onerror = (e) => {
|
|
16732
16957
|
console.error('📸 WebWorker 错误:', e);
|
|
16958
|
+
if (!this.options.silentMode) {
|
|
16959
|
+
console.warn('📸 Worker 压缩失败,使用原始截图');
|
|
16960
|
+
}
|
|
16733
16961
|
};
|
|
16734
16962
|
// 注意:不要立即 revokeObjectURL,因为 Worker 需要这个 URL 保持有效
|
|
16735
16963
|
// 在 destroy() 方法中清理 Worker 时再 revoke
|
|
16736
|
-
// URL.revokeObjectURL(workerUrl) // 已移除,在 destroy 时清理
|
|
16737
16964
|
return newWorker;
|
|
16738
16965
|
}
|
|
16739
16966
|
catch (err) {
|
|
@@ -16811,7 +17038,7 @@ class ScreenshotManager {
|
|
|
16811
17038
|
const encoder = new TextEncoder();
|
|
16812
17039
|
let offset = 0;
|
|
16813
17040
|
// sign: 8字节 (BigInt64)
|
|
16814
|
-
view.setBigInt64(offset, BigInt(config.sign)
|
|
17041
|
+
view.setBigInt64(offset, BigInt(config.sign));
|
|
16815
17042
|
offset += 8;
|
|
16816
17043
|
// type: 1字节 (Uint8)
|
|
16817
17044
|
view.setUint8(offset, config.type);
|