ibc-ai-web-sdk 2.0.3 → 2.0.5
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/README.md +23 -1
- package/dist/index.cjs.js +1236 -372
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +1236 -372
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +1236 -372
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -1
- package/index.d.ts +35 -1
- package/package.json +2 -2
package/dist/index.cjs.js
CHANGED
|
@@ -225,7 +225,8 @@ class AIChatClient {
|
|
|
225
225
|
return token;
|
|
226
226
|
}).catch(error => {
|
|
227
227
|
if (silent) {
|
|
228
|
-
|
|
228
|
+
const errMsg = error && (error.message || String(error)) || 'unknown error';
|
|
229
|
+
console.warn('[AIChatClient] Silent token refresh failed (reason=' + reason + '):', errMsg);
|
|
229
230
|
return this.config.token || '';
|
|
230
231
|
}
|
|
231
232
|
this.stopBackgroundRefresh();
|
|
@@ -383,8 +384,25 @@ class AIChatClient {
|
|
|
383
384
|
if (conversationId) payload.conversationId = conversationId;
|
|
384
385
|
const attachmentIds = options.attachmentIds || this.normalizeAttachmentIds(options.attachments);
|
|
385
386
|
if (attachmentIds.length > 0) payload.attachmentIds = attachmentIds;
|
|
386
|
-
|
|
387
|
-
if (bizParams)
|
|
387
|
+
let bizParams = options.bizParams || options.extendInfo || this.config.extendInfo;
|
|
388
|
+
if (bizParams) {
|
|
389
|
+
if (typeof bizParams === 'string') {
|
|
390
|
+
try {
|
|
391
|
+
bizParams = JSON.parse(bizParams);
|
|
392
|
+
} catch (e) {
|
|
393
|
+
bizParams = {};
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
} else {
|
|
397
|
+
bizParams = {};
|
|
398
|
+
}
|
|
399
|
+
// P3: 将页面上下文合并到 bizParams(contextMode='bizParams' 时由 dialog 传入)
|
|
400
|
+
if (options.context) {
|
|
401
|
+
Object.assign(bizParams, options.context);
|
|
402
|
+
}
|
|
403
|
+
if (Object.keys(bizParams).length > 0) {
|
|
404
|
+
payload.bizParams = JSON.stringify(bizParams);
|
|
405
|
+
}
|
|
388
406
|
return payload;
|
|
389
407
|
}
|
|
390
408
|
normalizeAttachmentIds(attachments) {
|
|
@@ -2719,12 +2737,855 @@ function createDOMPurify() {
|
|
|
2719
2737
|
}
|
|
2720
2738
|
var purify = createDOMPurify();
|
|
2721
2739
|
|
|
2740
|
+
/**
|
|
2741
|
+
* 预设主题配置
|
|
2742
|
+
* 提供多种常用主题,用户可以直接使用或自定义
|
|
2743
|
+
*/
|
|
2744
|
+
|
|
2745
|
+
/**
|
|
2746
|
+
* 默认主题(蓝色渐变)
|
|
2747
|
+
*/
|
|
2748
|
+
const DEFAULT_THEME = {
|
|
2749
|
+
name: 'default',
|
|
2750
|
+
label: '默认主题',
|
|
2751
|
+
colors: {
|
|
2752
|
+
primary: '#1890ff',
|
|
2753
|
+
primaryLight: '#40a9ff',
|
|
2754
|
+
primaryDark: '#096dd9',
|
|
2755
|
+
secondary: '#722ed1',
|
|
2756
|
+
background: '#ffffff',
|
|
2757
|
+
backgroundGradient: '#f8fafc',
|
|
2758
|
+
text: '#1e293b',
|
|
2759
|
+
textSecondary: '#64748b',
|
|
2760
|
+
userBubble: 'linear-gradient(135deg, #1890ff, #40a9ff)',
|
|
2761
|
+
aiBubble: '#ffffff',
|
|
2762
|
+
headerGradient: 'linear-gradient(90deg, rgba(24, 144, 255, 0.08), rgba(114, 46, 209, 0.08))',
|
|
2763
|
+
border: 'rgba(24, 144, 255, 0.15)',
|
|
2764
|
+
shadow: 'rgba(24, 144, 255, 0.12)',
|
|
2765
|
+
inputBackground: '#f8fafc',
|
|
2766
|
+
inputBorder: '#e2e8f0',
|
|
2767
|
+
loading: '#64748b',
|
|
2768
|
+
success: '#52c41a',
|
|
2769
|
+
error: '#ff4d4f',
|
|
2770
|
+
warning: '#faad14'
|
|
2771
|
+
},
|
|
2772
|
+
borderRadius: {
|
|
2773
|
+
dialog: '16px',
|
|
2774
|
+
bubble: '12px',
|
|
2775
|
+
button: '50%',
|
|
2776
|
+
input: '28px',
|
|
2777
|
+
small: '6px',
|
|
2778
|
+
medium: '12px'
|
|
2779
|
+
},
|
|
2780
|
+
fontSize: {
|
|
2781
|
+
title: '15px',
|
|
2782
|
+
welcomeText: '17px',
|
|
2783
|
+
welcomeDesc: '13px',
|
|
2784
|
+
message: '14px',
|
|
2785
|
+
time: '11px',
|
|
2786
|
+
small: '11px'
|
|
2787
|
+
},
|
|
2788
|
+
boxShadow: {
|
|
2789
|
+
dialog: '0 0 30px rgba(24, 144, 255, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
2790
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
2791
|
+
userBubble: '0 4px 12px rgba(24, 144, 255, 0.25)',
|
|
2792
|
+
button: '0 4px 12px rgba(24, 144, 255, 0.35)'
|
|
2793
|
+
}
|
|
2794
|
+
};
|
|
2795
|
+
|
|
2796
|
+
/**
|
|
2797
|
+
* 深色主题
|
|
2798
|
+
*/
|
|
2799
|
+
const DARK_THEME = {
|
|
2800
|
+
name: 'dark',
|
|
2801
|
+
label: '深色主题',
|
|
2802
|
+
colors: {
|
|
2803
|
+
primary: '#40a9ff',
|
|
2804
|
+
primaryLight: '#69c0ff',
|
|
2805
|
+
primaryDark: '#1890ff',
|
|
2806
|
+
secondary: '#9254de',
|
|
2807
|
+
background: '#0f172a',
|
|
2808
|
+
backgroundGradient: '#1e293b',
|
|
2809
|
+
text: '#f1f5f9',
|
|
2810
|
+
textSecondary: '#94a3b8',
|
|
2811
|
+
userBubble: 'linear-gradient(135deg, #1890ff, #40a9ff)',
|
|
2812
|
+
aiBubble: '#1e293b',
|
|
2813
|
+
headerGradient: 'linear-gradient(90deg, rgba(64, 169, 255, 0.15), rgba(146, 84, 222, 0.15))',
|
|
2814
|
+
border: 'rgba(64, 169, 255, 0.3)',
|
|
2815
|
+
shadow: 'rgba(0, 0, 0, 0.3)',
|
|
2816
|
+
inputBackground: '#1e293b',
|
|
2817
|
+
inputBorder: '#334155',
|
|
2818
|
+
loading: '#94a3b8',
|
|
2819
|
+
success: '#73d13d',
|
|
2820
|
+
error: '#ff7875',
|
|
2821
|
+
warning: '#ffd666'
|
|
2822
|
+
},
|
|
2823
|
+
borderRadius: {
|
|
2824
|
+
dialog: '16px',
|
|
2825
|
+
bubble: '12px',
|
|
2826
|
+
button: '50%',
|
|
2827
|
+
input: '28px',
|
|
2828
|
+
small: '6px',
|
|
2829
|
+
medium: '12px'
|
|
2830
|
+
},
|
|
2831
|
+
fontSize: {
|
|
2832
|
+
title: '15px',
|
|
2833
|
+
welcomeText: '17px',
|
|
2834
|
+
welcomeDesc: '13px',
|
|
2835
|
+
message: '14px',
|
|
2836
|
+
time: '11px',
|
|
2837
|
+
small: '11px'
|
|
2838
|
+
},
|
|
2839
|
+
boxShadow: {
|
|
2840
|
+
dialog: '0 0 30px rgba(64, 169, 255, 0.15), 0 8px 32px rgba(0, 0, 0, 0.4)',
|
|
2841
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.2)',
|
|
2842
|
+
userBubble: '0 4px 12px rgba(24, 144, 255, 0.3)',
|
|
2843
|
+
button: '0 4px 12px rgba(24, 144, 255, 0.4)'
|
|
2844
|
+
}
|
|
2845
|
+
};
|
|
2846
|
+
|
|
2847
|
+
/**
|
|
2848
|
+
* 清新主题(绿色系)
|
|
2849
|
+
*/
|
|
2850
|
+
const FRESH_THEME = {
|
|
2851
|
+
name: 'fresh',
|
|
2852
|
+
label: '清新主题',
|
|
2853
|
+
colors: {
|
|
2854
|
+
primary: '#52c41a',
|
|
2855
|
+
primaryLight: '#73d13d',
|
|
2856
|
+
primaryDark: '#389e0d',
|
|
2857
|
+
secondary: '#1890ff',
|
|
2858
|
+
background: '#ffffff',
|
|
2859
|
+
backgroundGradient: '#f6ffed',
|
|
2860
|
+
text: '#1e293b',
|
|
2861
|
+
textSecondary: '#64748b',
|
|
2862
|
+
userBubble: 'linear-gradient(135deg, #52c41a, #73d13d)',
|
|
2863
|
+
aiBubble: '#ffffff',
|
|
2864
|
+
headerGradient: 'linear-gradient(90deg, rgba(82, 196, 26, 0.08), rgba(24, 144, 255, 0.08))',
|
|
2865
|
+
border: 'rgba(82, 196, 26, 0.15)',
|
|
2866
|
+
shadow: 'rgba(82, 196, 26, 0.12)',
|
|
2867
|
+
inputBackground: '#f6ffed',
|
|
2868
|
+
inputBorder: '#d9f7be',
|
|
2869
|
+
loading: '#64748b',
|
|
2870
|
+
success: '#52c41a',
|
|
2871
|
+
error: '#ff4d4f',
|
|
2872
|
+
warning: '#faad14'
|
|
2873
|
+
},
|
|
2874
|
+
borderRadius: {
|
|
2875
|
+
dialog: '20px',
|
|
2876
|
+
bubble: '16px',
|
|
2877
|
+
button: '50%',
|
|
2878
|
+
input: '32px',
|
|
2879
|
+
small: '8px',
|
|
2880
|
+
medium: '16px'
|
|
2881
|
+
},
|
|
2882
|
+
fontSize: {
|
|
2883
|
+
title: '15px',
|
|
2884
|
+
welcomeText: '17px',
|
|
2885
|
+
welcomeDesc: '13px',
|
|
2886
|
+
message: '14px',
|
|
2887
|
+
time: '11px',
|
|
2888
|
+
small: '11px'
|
|
2889
|
+
},
|
|
2890
|
+
boxShadow: {
|
|
2891
|
+
dialog: '0 0 30px rgba(82, 196, 26, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
2892
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
2893
|
+
userBubble: '0 4px 12px rgba(82, 196, 26, 0.25)',
|
|
2894
|
+
button: '0 4px 12px rgba(82, 196, 26, 0.35)'
|
|
2895
|
+
}
|
|
2896
|
+
};
|
|
2897
|
+
|
|
2898
|
+
/**
|
|
2899
|
+
* 活力主题(橙色系)
|
|
2900
|
+
*/
|
|
2901
|
+
const VIBRANT_THEME = {
|
|
2902
|
+
name: 'vibrant',
|
|
2903
|
+
label: '活力主题',
|
|
2904
|
+
colors: {
|
|
2905
|
+
primary: '#fa8c16',
|
|
2906
|
+
primaryLight: '#ffa940',
|
|
2907
|
+
primaryDark: '#d46b08',
|
|
2908
|
+
secondary: '#f5222d',
|
|
2909
|
+
background: '#ffffff',
|
|
2910
|
+
backgroundGradient: '#fff7e6',
|
|
2911
|
+
text: '#1e293b',
|
|
2912
|
+
textSecondary: '#64748b',
|
|
2913
|
+
userBubble: 'linear-gradient(135deg, #fa8c16, #ffa940)',
|
|
2914
|
+
aiBubble: '#ffffff',
|
|
2915
|
+
headerGradient: 'linear-gradient(90deg, rgba(250, 140, 22, 0.08), rgba(245, 34, 45, 0.08))',
|
|
2916
|
+
border: 'rgba(250, 140, 22, 0.15)',
|
|
2917
|
+
shadow: 'rgba(250, 140, 22, 0.12)',
|
|
2918
|
+
inputBackground: '#fff7e6',
|
|
2919
|
+
inputBorder: '#ffd591',
|
|
2920
|
+
loading: '#64748b',
|
|
2921
|
+
success: '#52c41a',
|
|
2922
|
+
error: '#ff4d4f',
|
|
2923
|
+
warning: '#faad14'
|
|
2924
|
+
},
|
|
2925
|
+
borderRadius: {
|
|
2926
|
+
dialog: '12px',
|
|
2927
|
+
bubble: '10px',
|
|
2928
|
+
button: '50%',
|
|
2929
|
+
input: '24px',
|
|
2930
|
+
small: '4px',
|
|
2931
|
+
medium: '10px'
|
|
2932
|
+
},
|
|
2933
|
+
fontSize: {
|
|
2934
|
+
title: '15px',
|
|
2935
|
+
welcomeText: '17px',
|
|
2936
|
+
welcomeDesc: '13px',
|
|
2937
|
+
message: '14px',
|
|
2938
|
+
time: '11px',
|
|
2939
|
+
small: '11px'
|
|
2940
|
+
},
|
|
2941
|
+
boxShadow: {
|
|
2942
|
+
dialog: '0 0 30px rgba(250, 140, 22, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
2943
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
2944
|
+
userBubble: '0 4px 12px rgba(250, 140, 22, 0.25)',
|
|
2945
|
+
button: '0 4px 12px rgba(250, 140, 22, 0.35)'
|
|
2946
|
+
}
|
|
2947
|
+
};
|
|
2948
|
+
|
|
2949
|
+
/**
|
|
2950
|
+
* 浪漫主题(粉色系)
|
|
2951
|
+
*/
|
|
2952
|
+
const ROMANTIC_THEME = {
|
|
2953
|
+
name: 'romantic',
|
|
2954
|
+
label: '浪漫主题',
|
|
2955
|
+
colors: {
|
|
2956
|
+
primary: '#eb2f96',
|
|
2957
|
+
primaryLight: '#fb6f92',
|
|
2958
|
+
primaryDark: '#c41d7f',
|
|
2959
|
+
secondary: '#722ed1',
|
|
2960
|
+
background: '#ffffff',
|
|
2961
|
+
backgroundGradient: '#fff0f6',
|
|
2962
|
+
text: '#1e293b',
|
|
2963
|
+
textSecondary: '#64748b',
|
|
2964
|
+
userBubble: 'linear-gradient(135deg, #eb2f96, #fb6f92)',
|
|
2965
|
+
aiBubble: '#ffffff',
|
|
2966
|
+
headerGradient: 'linear-gradient(90deg, rgba(235, 47, 150, 0.08), rgba(114, 46, 209, 0.08))',
|
|
2967
|
+
border: 'rgba(235, 47, 150, 0.15)',
|
|
2968
|
+
shadow: 'rgba(235, 47, 150, 0.12)',
|
|
2969
|
+
inputBackground: '#fff0f6',
|
|
2970
|
+
inputBorder: '#ffadd2',
|
|
2971
|
+
loading: '#64748b',
|
|
2972
|
+
success: '#52c41a',
|
|
2973
|
+
error: '#ff4d4f',
|
|
2974
|
+
warning: '#faad14'
|
|
2975
|
+
},
|
|
2976
|
+
borderRadius: {
|
|
2977
|
+
dialog: '24px',
|
|
2978
|
+
bubble: '16px',
|
|
2979
|
+
button: '50%',
|
|
2980
|
+
input: '32px',
|
|
2981
|
+
small: '8px',
|
|
2982
|
+
medium: '16px'
|
|
2983
|
+
},
|
|
2984
|
+
fontSize: {
|
|
2985
|
+
title: '15px',
|
|
2986
|
+
welcomeText: '17px',
|
|
2987
|
+
welcomeDesc: '13px',
|
|
2988
|
+
message: '14px',
|
|
2989
|
+
time: '11px',
|
|
2990
|
+
small: '11px'
|
|
2991
|
+
},
|
|
2992
|
+
boxShadow: {
|
|
2993
|
+
dialog: '0 0 30px rgba(235, 47, 150, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
2994
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
2995
|
+
userBubble: '0 4px 12px rgba(235, 47, 150, 0.25)',
|
|
2996
|
+
button: '0 4px 12px rgba(235, 47, 150, 0.35)'
|
|
2997
|
+
}
|
|
2998
|
+
};
|
|
2999
|
+
|
|
3000
|
+
/**
|
|
3001
|
+
* 紫色主题(优雅神秘)
|
|
3002
|
+
*/
|
|
3003
|
+
const PURPLE_THEME = {
|
|
3004
|
+
name: 'purple',
|
|
3005
|
+
label: '紫色主题',
|
|
3006
|
+
colors: {
|
|
3007
|
+
primary: '#722ed1',
|
|
3008
|
+
primaryLight: '#9254de',
|
|
3009
|
+
primaryDark: '#531dab',
|
|
3010
|
+
secondary: '#1890ff',
|
|
3011
|
+
background: '#ffffff',
|
|
3012
|
+
backgroundGradient: '#f9f0ff',
|
|
3013
|
+
text: '#1e293b',
|
|
3014
|
+
textSecondary: '#64748b',
|
|
3015
|
+
userBubble: 'linear-gradient(135deg, #722ed1, #9254de)',
|
|
3016
|
+
aiBubble: '#ffffff',
|
|
3017
|
+
headerGradient: 'linear-gradient(90deg, rgba(114, 46, 209, 0.08), rgba(24, 144, 255, 0.08))',
|
|
3018
|
+
border: 'rgba(114, 46, 209, 0.15)',
|
|
3019
|
+
shadow: 'rgba(114, 46, 209, 0.12)',
|
|
3020
|
+
inputBackground: '#f9f0ff',
|
|
3021
|
+
inputBorder: '#d3adf7',
|
|
3022
|
+
loading: '#64748b',
|
|
3023
|
+
success: '#52c41a',
|
|
3024
|
+
error: '#ff4d4f',
|
|
3025
|
+
warning: '#faad14'
|
|
3026
|
+
},
|
|
3027
|
+
borderRadius: {
|
|
3028
|
+
dialog: '16px',
|
|
3029
|
+
bubble: '12px',
|
|
3030
|
+
button: '50%',
|
|
3031
|
+
input: '28px',
|
|
3032
|
+
small: '6px',
|
|
3033
|
+
medium: '12px'
|
|
3034
|
+
},
|
|
3035
|
+
fontSize: {
|
|
3036
|
+
title: '15px',
|
|
3037
|
+
welcomeText: '17px',
|
|
3038
|
+
welcomeDesc: '13px',
|
|
3039
|
+
message: '14px',
|
|
3040
|
+
time: '11px',
|
|
3041
|
+
small: '11px'
|
|
3042
|
+
},
|
|
3043
|
+
boxShadow: {
|
|
3044
|
+
dialog: '0 0 30px rgba(114, 46, 209, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
3045
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
3046
|
+
userBubble: '0 4px 12px rgba(114, 46, 209, 0.25)',
|
|
3047
|
+
button: '0 4px 12px rgba(114, 46, 209, 0.35)'
|
|
3048
|
+
}
|
|
3049
|
+
};
|
|
3050
|
+
|
|
3051
|
+
/**
|
|
3052
|
+
* 海洋主题(深蓝深海)
|
|
3053
|
+
*/
|
|
3054
|
+
const OCEAN_THEME = {
|
|
3055
|
+
name: 'ocean',
|
|
3056
|
+
label: '海洋主题',
|
|
3057
|
+
colors: {
|
|
3058
|
+
primary: '#0077b6',
|
|
3059
|
+
primaryLight: '#00b4d8',
|
|
3060
|
+
primaryDark: '#023e8a',
|
|
3061
|
+
secondary: '#00b4d8',
|
|
3062
|
+
background: '#ffffff',
|
|
3063
|
+
backgroundGradient: '#f0f9ff',
|
|
3064
|
+
text: '#1e293b',
|
|
3065
|
+
textSecondary: '#64748b',
|
|
3066
|
+
userBubble: 'linear-gradient(135deg, #0077b6, #00b4d8)',
|
|
3067
|
+
aiBubble: '#ffffff',
|
|
3068
|
+
headerGradient: 'linear-gradient(90deg, rgba(0, 119, 182, 0.08), rgba(0, 180, 216, 0.08))',
|
|
3069
|
+
border: 'rgba(0, 119, 182, 0.15)',
|
|
3070
|
+
shadow: 'rgba(0, 119, 182, 0.12)',
|
|
3071
|
+
inputBackground: '#f0f9ff',
|
|
3072
|
+
inputBorder: '#bae6fd',
|
|
3073
|
+
loading: '#64748b',
|
|
3074
|
+
success: '#52c41a',
|
|
3075
|
+
error: '#ff4d4f',
|
|
3076
|
+
warning: '#faad14'
|
|
3077
|
+
},
|
|
3078
|
+
borderRadius: {
|
|
3079
|
+
dialog: '14px',
|
|
3080
|
+
bubble: '10px',
|
|
3081
|
+
button: '50%',
|
|
3082
|
+
input: '28px',
|
|
3083
|
+
small: '6px',
|
|
3084
|
+
medium: '12px'
|
|
3085
|
+
},
|
|
3086
|
+
fontSize: {
|
|
3087
|
+
title: '15px',
|
|
3088
|
+
welcomeText: '17px',
|
|
3089
|
+
welcomeDesc: '13px',
|
|
3090
|
+
message: '14px',
|
|
3091
|
+
time: '11px',
|
|
3092
|
+
small: '11px'
|
|
3093
|
+
},
|
|
3094
|
+
boxShadow: {
|
|
3095
|
+
dialog: '0 0 30px rgba(0, 119, 182, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
3096
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
3097
|
+
userBubble: '0 4px 12px rgba(0, 119, 182, 0.25)',
|
|
3098
|
+
button: '0 4px 12px rgba(0, 119, 182, 0.35)'
|
|
3099
|
+
}
|
|
3100
|
+
};
|
|
3101
|
+
|
|
3102
|
+
/**
|
|
3103
|
+
* 暮光主题(紫罗兰渐变)
|
|
3104
|
+
*/
|
|
3105
|
+
const TWILIGHT_THEME = {
|
|
3106
|
+
name: 'twilight',
|
|
3107
|
+
label: '暮光主题',
|
|
3108
|
+
colors: {
|
|
3109
|
+
primary: '#9333ea',
|
|
3110
|
+
primaryLight: '#a855f7',
|
|
3111
|
+
primaryDark: '#7e22ce',
|
|
3112
|
+
secondary: '#ec4899',
|
|
3113
|
+
background: '#ffffff',
|
|
3114
|
+
backgroundGradient: '#faf5ff',
|
|
3115
|
+
text: '#1e293b',
|
|
3116
|
+
textSecondary: '#64748b',
|
|
3117
|
+
userBubble: 'linear-gradient(135deg, #9333ea, #ec4899)',
|
|
3118
|
+
aiBubble: '#ffffff',
|
|
3119
|
+
headerGradient: 'linear-gradient(90deg, rgba(147, 51, 234, 0.08), rgba(236, 72, 153, 0.08))',
|
|
3120
|
+
border: 'rgba(147, 51, 234, 0.15)',
|
|
3121
|
+
shadow: 'rgba(147, 51, 234, 0.12)',
|
|
3122
|
+
inputBackground: '#faf5ff',
|
|
3123
|
+
inputBorder: '#e9d5ff',
|
|
3124
|
+
loading: '#64748b',
|
|
3125
|
+
success: '#52c41a',
|
|
3126
|
+
error: '#ff4d4f',
|
|
3127
|
+
warning: '#faad14'
|
|
3128
|
+
},
|
|
3129
|
+
borderRadius: {
|
|
3130
|
+
dialog: '18px',
|
|
3131
|
+
bubble: '14px',
|
|
3132
|
+
button: '50%',
|
|
3133
|
+
input: '30px',
|
|
3134
|
+
small: '8px',
|
|
3135
|
+
medium: '14px'
|
|
3136
|
+
},
|
|
3137
|
+
fontSize: {
|
|
3138
|
+
title: '15px',
|
|
3139
|
+
welcomeText: '17px',
|
|
3140
|
+
welcomeDesc: '13px',
|
|
3141
|
+
message: '14px',
|
|
3142
|
+
time: '11px',
|
|
3143
|
+
small: '11px'
|
|
3144
|
+
},
|
|
3145
|
+
boxShadow: {
|
|
3146
|
+
dialog: '0 0 30px rgba(147, 51, 234, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
3147
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
3148
|
+
userBubble: '0 4px 12px rgba(147, 51, 234, 0.25)',
|
|
3149
|
+
button: '0 4px 12px rgba(147, 51, 234, 0.35)'
|
|
3150
|
+
}
|
|
3151
|
+
};
|
|
3152
|
+
|
|
3153
|
+
/**
|
|
3154
|
+
* 薄荷主题(青绿色)
|
|
3155
|
+
*/
|
|
3156
|
+
const MINT_THEME = {
|
|
3157
|
+
name: 'mint',
|
|
3158
|
+
label: '薄荷主题',
|
|
3159
|
+
colors: {
|
|
3160
|
+
primary: '#14b8a6',
|
|
3161
|
+
primaryLight: '#2dd4bf',
|
|
3162
|
+
primaryDark: '#0d9488',
|
|
3163
|
+
secondary: '#06b6d4',
|
|
3164
|
+
background: '#ffffff',
|
|
3165
|
+
backgroundGradient: '#f0fdfa',
|
|
3166
|
+
text: '#1e293b',
|
|
3167
|
+
textSecondary: '#64748b',
|
|
3168
|
+
userBubble: 'linear-gradient(135deg, #14b8a6, #2dd4bf)',
|
|
3169
|
+
aiBubble: '#ffffff',
|
|
3170
|
+
headerGradient: 'linear-gradient(90deg, rgba(20, 184, 166, 0.08), rgba(6, 182, 212, 0.08))',
|
|
3171
|
+
border: 'rgba(20, 184, 166, 0.15)',
|
|
3172
|
+
shadow: 'rgba(20, 184, 166, 0.12)',
|
|
3173
|
+
inputBackground: '#f0fdfa',
|
|
3174
|
+
inputBorder: '#99f6e4',
|
|
3175
|
+
loading: '#64748b',
|
|
3176
|
+
success: '#52c41a',
|
|
3177
|
+
error: '#ff4d4f',
|
|
3178
|
+
warning: '#faad14'
|
|
3179
|
+
},
|
|
3180
|
+
borderRadius: {
|
|
3181
|
+
dialog: '16px',
|
|
3182
|
+
bubble: '12px',
|
|
3183
|
+
button: '50%',
|
|
3184
|
+
input: '28px',
|
|
3185
|
+
small: '6px',
|
|
3186
|
+
medium: '12px'
|
|
3187
|
+
},
|
|
3188
|
+
fontSize: {
|
|
3189
|
+
title: '15px',
|
|
3190
|
+
welcomeText: '17px',
|
|
3191
|
+
welcomeDesc: '13px',
|
|
3192
|
+
message: '14px',
|
|
3193
|
+
time: '11px',
|
|
3194
|
+
small: '11px'
|
|
3195
|
+
},
|
|
3196
|
+
boxShadow: {
|
|
3197
|
+
dialog: '0 0 30px rgba(20, 184, 166, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
3198
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
3199
|
+
userBubble: '0 4px 12px rgba(20, 184, 166, 0.25)',
|
|
3200
|
+
button: '0 4px 12px rgba(20, 184, 166, 0.35)'
|
|
3201
|
+
}
|
|
3202
|
+
};
|
|
3203
|
+
|
|
3204
|
+
/**
|
|
3205
|
+
* 玫瑰主题(深红色)
|
|
3206
|
+
*/
|
|
3207
|
+
const ROSE_THEME = {
|
|
3208
|
+
name: 'rose',
|
|
3209
|
+
label: '玫瑰主题',
|
|
3210
|
+
colors: {
|
|
3211
|
+
primary: '#e11d48',
|
|
3212
|
+
primaryLight: '#fb7185',
|
|
3213
|
+
primaryDark: '#be123c',
|
|
3214
|
+
secondary: '#f43f5e',
|
|
3215
|
+
background: '#ffffff',
|
|
3216
|
+
backgroundGradient: '#fff1f2',
|
|
3217
|
+
text: '#1e293b',
|
|
3218
|
+
textSecondary: '#64748b',
|
|
3219
|
+
userBubble: 'linear-gradient(135deg, #e11d48, #fb7185)',
|
|
3220
|
+
aiBubble: '#ffffff',
|
|
3221
|
+
headerGradient: 'linear-gradient(90deg, rgba(225, 29, 72, 0.08), rgba(244, 63, 94, 0.08))',
|
|
3222
|
+
border: 'rgba(225, 29, 72, 0.15)',
|
|
3223
|
+
shadow: 'rgba(225, 29, 72, 0.12)',
|
|
3224
|
+
inputBackground: '#fff1f2',
|
|
3225
|
+
inputBorder: '#fecdd3',
|
|
3226
|
+
loading: '#64748b',
|
|
3227
|
+
success: '#52c41a',
|
|
3228
|
+
error: '#ff4d4f',
|
|
3229
|
+
warning: '#faad14'
|
|
3230
|
+
},
|
|
3231
|
+
borderRadius: {
|
|
3232
|
+
dialog: '16px',
|
|
3233
|
+
bubble: '12px',
|
|
3234
|
+
button: '50%',
|
|
3235
|
+
input: '28px',
|
|
3236
|
+
small: '6px',
|
|
3237
|
+
medium: '12px'
|
|
3238
|
+
},
|
|
3239
|
+
fontSize: {
|
|
3240
|
+
title: '15px',
|
|
3241
|
+
welcomeText: '17px',
|
|
3242
|
+
welcomeDesc: '13px',
|
|
3243
|
+
message: '14px',
|
|
3244
|
+
time: '11px',
|
|
3245
|
+
small: '11px'
|
|
3246
|
+
},
|
|
3247
|
+
boxShadow: {
|
|
3248
|
+
dialog: '0 0 30px rgba(225, 29, 72, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
3249
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
3250
|
+
userBubble: '0 4px 12px rgba(225, 29, 72, 0.25)',
|
|
3251
|
+
button: '0 4px 12px rgba(225, 29, 72, 0.35)'
|
|
3252
|
+
}
|
|
3253
|
+
};
|
|
3254
|
+
|
|
3255
|
+
/**
|
|
3256
|
+
* 极光主题(蓝绿渐变)
|
|
3257
|
+
*/
|
|
3258
|
+
const AURORA_THEME = {
|
|
3259
|
+
name: 'aurora',
|
|
3260
|
+
label: '极光主题',
|
|
3261
|
+
colors: {
|
|
3262
|
+
primary: '#0ea5e9',
|
|
3263
|
+
primaryLight: '#38bdf8',
|
|
3264
|
+
primaryDark: '#0284c7',
|
|
3265
|
+
secondary: '#10b981',
|
|
3266
|
+
background: '#ffffff',
|
|
3267
|
+
backgroundGradient: '#f0f9ff',
|
|
3268
|
+
text: '#1e293b',
|
|
3269
|
+
textSecondary: '#64748b',
|
|
3270
|
+
userBubble: 'linear-gradient(135deg, #0ea5e9, #10b981)',
|
|
3271
|
+
aiBubble: '#ffffff',
|
|
3272
|
+
headerGradient: 'linear-gradient(90deg, rgba(14, 165, 233, 0.08), rgba(16, 185, 129, 0.08))',
|
|
3273
|
+
border: 'rgba(14, 165, 233, 0.15)',
|
|
3274
|
+
shadow: 'rgba(14, 165, 233, 0.12)',
|
|
3275
|
+
inputBackground: '#f0f9ff',
|
|
3276
|
+
inputBorder: '#bae6fd',
|
|
3277
|
+
loading: '#64748b',
|
|
3278
|
+
success: '#52c41a',
|
|
3279
|
+
error: '#ff4d4f',
|
|
3280
|
+
warning: '#faad14'
|
|
3281
|
+
},
|
|
3282
|
+
borderRadius: {
|
|
3283
|
+
dialog: '20px',
|
|
3284
|
+
bubble: '14px',
|
|
3285
|
+
button: '50%',
|
|
3286
|
+
input: '30px',
|
|
3287
|
+
small: '8px',
|
|
3288
|
+
medium: '14px'
|
|
3289
|
+
},
|
|
3290
|
+
fontSize: {
|
|
3291
|
+
title: '15px',
|
|
3292
|
+
welcomeText: '17px',
|
|
3293
|
+
welcomeDesc: '13px',
|
|
3294
|
+
message: '14px',
|
|
3295
|
+
time: '11px',
|
|
3296
|
+
small: '11px'
|
|
3297
|
+
},
|
|
3298
|
+
boxShadow: {
|
|
3299
|
+
dialog: '0 0 30px rgba(14, 165, 233, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
3300
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
3301
|
+
userBubble: '0 4px 12px rgba(14, 165, 233, 0.25)',
|
|
3302
|
+
button: '0 4px 12px rgba(14, 165, 233, 0.35)'
|
|
3303
|
+
}
|
|
3304
|
+
};
|
|
3305
|
+
|
|
3306
|
+
/**
|
|
3307
|
+
* 薰衣草主题(淡紫色)
|
|
3308
|
+
*/
|
|
3309
|
+
const LAVENDER_THEME = {
|
|
3310
|
+
name: 'lavender',
|
|
3311
|
+
label: '薰衣草主题',
|
|
3312
|
+
colors: {
|
|
3313
|
+
primary: '#8b5cf6',
|
|
3314
|
+
primaryLight: '#a78bfa',
|
|
3315
|
+
primaryDark: '#7c3aed',
|
|
3316
|
+
secondary: '#c084fc',
|
|
3317
|
+
background: '#ffffff',
|
|
3318
|
+
backgroundGradient: '#faf5ff',
|
|
3319
|
+
text: '#1e293b',
|
|
3320
|
+
textSecondary: '#64748b',
|
|
3321
|
+
userBubble: 'linear-gradient(135deg, #8b5cf6, #c084fc)',
|
|
3322
|
+
aiBubble: '#ffffff',
|
|
3323
|
+
headerGradient: 'linear-gradient(90deg, rgba(139, 92, 246, 0.08), rgba(192, 132, 252, 0.08))',
|
|
3324
|
+
border: 'rgba(139, 92, 246, 0.15)',
|
|
3325
|
+
shadow: 'rgba(139, 92, 246, 0.12)',
|
|
3326
|
+
inputBackground: '#faf5ff',
|
|
3327
|
+
inputBorder: '#ddd6fe',
|
|
3328
|
+
loading: '#64748b',
|
|
3329
|
+
success: '#52c41a',
|
|
3330
|
+
error: '#ff4d4f',
|
|
3331
|
+
warning: '#faad14'
|
|
3332
|
+
},
|
|
3333
|
+
borderRadius: {
|
|
3334
|
+
dialog: '22px',
|
|
3335
|
+
bubble: '16px',
|
|
3336
|
+
button: '50%',
|
|
3337
|
+
input: '32px',
|
|
3338
|
+
small: '8px',
|
|
3339
|
+
medium: '16px'
|
|
3340
|
+
},
|
|
3341
|
+
fontSize: {
|
|
3342
|
+
title: '15px',
|
|
3343
|
+
welcomeText: '17px',
|
|
3344
|
+
welcomeDesc: '13px',
|
|
3345
|
+
message: '14px',
|
|
3346
|
+
time: '11px',
|
|
3347
|
+
small: '11px'
|
|
3348
|
+
},
|
|
3349
|
+
boxShadow: {
|
|
3350
|
+
dialog: '0 0 30px rgba(139, 92, 246, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
3351
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
3352
|
+
userBubble: '0 4px 12px rgba(139, 92, 246, 0.25)',
|
|
3353
|
+
button: '0 4px 12px rgba(139, 92, 246, 0.35)'
|
|
3354
|
+
}
|
|
3355
|
+
};
|
|
3356
|
+
|
|
3357
|
+
/**
|
|
3358
|
+
* 珊瑚主题(粉橙色)
|
|
3359
|
+
*/
|
|
3360
|
+
const CORAL_THEME = {
|
|
3361
|
+
name: 'coral',
|
|
3362
|
+
label: '珊瑚主题',
|
|
3363
|
+
colors: {
|
|
3364
|
+
primary: '#f97316',
|
|
3365
|
+
primaryLight: '#fb923c',
|
|
3366
|
+
primaryDark: '#ea580c',
|
|
3367
|
+
secondary: '#f43f5e',
|
|
3368
|
+
background: '#ffffff',
|
|
3369
|
+
backgroundGradient: '#fff7ed',
|
|
3370
|
+
text: '#1e293b',
|
|
3371
|
+
textSecondary: '#64748b',
|
|
3372
|
+
userBubble: 'linear-gradient(135deg, #f97316, #fb923c)',
|
|
3373
|
+
aiBubble: '#ffffff',
|
|
3374
|
+
headerGradient: 'linear-gradient(90deg, rgba(249, 115, 22, 0.08), rgba(244, 63, 94, 0.08))',
|
|
3375
|
+
border: 'rgba(249, 115, 22, 0.15)',
|
|
3376
|
+
shadow: 'rgba(249, 115, 22, 0.12)',
|
|
3377
|
+
inputBackground: '#fff7ed',
|
|
3378
|
+
inputBorder: '#fed7aa',
|
|
3379
|
+
loading: '#64748b',
|
|
3380
|
+
success: '#52c41a',
|
|
3381
|
+
error: '#ff4d4f',
|
|
3382
|
+
warning: '#faad14'
|
|
3383
|
+
},
|
|
3384
|
+
borderRadius: {
|
|
3385
|
+
dialog: '14px',
|
|
3386
|
+
bubble: '10px',
|
|
3387
|
+
button: '50%',
|
|
3388
|
+
input: '26px',
|
|
3389
|
+
small: '6px',
|
|
3390
|
+
medium: '10px'
|
|
3391
|
+
},
|
|
3392
|
+
fontSize: {
|
|
3393
|
+
title: '15px',
|
|
3394
|
+
welcomeText: '17px',
|
|
3395
|
+
welcomeDesc: '13px',
|
|
3396
|
+
message: '14px',
|
|
3397
|
+
time: '11px',
|
|
3398
|
+
small: '11px'
|
|
3399
|
+
},
|
|
3400
|
+
boxShadow: {
|
|
3401
|
+
dialog: '0 0 30px rgba(249, 115, 22, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
3402
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
3403
|
+
userBubble: '0 4px 12px rgba(249, 115, 22, 0.25)',
|
|
3404
|
+
button: '0 4px 12px rgba(249, 115, 22, 0.35)'
|
|
3405
|
+
}
|
|
3406
|
+
};
|
|
3407
|
+
|
|
3408
|
+
/**
|
|
3409
|
+
* 翡翠主题(深绿色)
|
|
3410
|
+
*/
|
|
3411
|
+
const JADE_THEME = {
|
|
3412
|
+
name: 'jade',
|
|
3413
|
+
label: '翡翠主题',
|
|
3414
|
+
colors: {
|
|
3415
|
+
primary: '#059669',
|
|
3416
|
+
primaryLight: '#10b981',
|
|
3417
|
+
primaryDark: '#047857',
|
|
3418
|
+
secondary: '#34d399',
|
|
3419
|
+
background: '#ffffff',
|
|
3420
|
+
backgroundGradient: '#f0fdf4',
|
|
3421
|
+
text: '#1e293b',
|
|
3422
|
+
textSecondary: '#64748b',
|
|
3423
|
+
userBubble: 'linear-gradient(135deg, #059669, #10b981)',
|
|
3424
|
+
aiBubble: '#ffffff',
|
|
3425
|
+
headerGradient: 'linear-gradient(90deg, rgba(5, 150, 105, 0.08), rgba(52, 211, 153, 0.08))',
|
|
3426
|
+
border: 'rgba(5, 150, 105, 0.15)',
|
|
3427
|
+
shadow: 'rgba(5, 150, 105, 0.12)',
|
|
3428
|
+
inputBackground: '#f0fdf4',
|
|
3429
|
+
inputBorder: '#bbf7d0',
|
|
3430
|
+
loading: '#64748b',
|
|
3431
|
+
success: '#52c41a',
|
|
3432
|
+
error: '#ff4d4f',
|
|
3433
|
+
warning: '#faad14'
|
|
3434
|
+
},
|
|
3435
|
+
borderRadius: {
|
|
3436
|
+
dialog: '16px',
|
|
3437
|
+
bubble: '12px',
|
|
3438
|
+
button: '50%',
|
|
3439
|
+
input: '28px',
|
|
3440
|
+
small: '6px',
|
|
3441
|
+
medium: '12px'
|
|
3442
|
+
},
|
|
3443
|
+
fontSize: {
|
|
3444
|
+
title: '15px',
|
|
3445
|
+
welcomeText: '17px',
|
|
3446
|
+
welcomeDesc: '13px',
|
|
3447
|
+
message: '14px',
|
|
3448
|
+
time: '11px',
|
|
3449
|
+
small: '11px'
|
|
3450
|
+
},
|
|
3451
|
+
boxShadow: {
|
|
3452
|
+
dialog: '0 0 30px rgba(5, 150, 105, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
3453
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
3454
|
+
userBubble: '0 4px 12px rgba(5, 150, 105, 0.25)',
|
|
3455
|
+
button: '0 4px 12px rgba(5, 150, 105, 0.35)'
|
|
3456
|
+
}
|
|
3457
|
+
};
|
|
3458
|
+
|
|
3459
|
+
/**
|
|
3460
|
+
* 星空主题(深蓝紫色)
|
|
3461
|
+
*/
|
|
3462
|
+
const STARSKY_THEME = {
|
|
3463
|
+
name: 'starsky',
|
|
3464
|
+
label: '星空主题',
|
|
3465
|
+
colors: {
|
|
3466
|
+
primary: '#6366f1',
|
|
3467
|
+
primaryLight: '#818cf8',
|
|
3468
|
+
primaryDark: '#4f46e5',
|
|
3469
|
+
secondary: '#a855f7',
|
|
3470
|
+
background: '#0f172a',
|
|
3471
|
+
backgroundGradient: '#1e1b4b',
|
|
3472
|
+
text: '#e2e8f0',
|
|
3473
|
+
textSecondary: '#94a3b8',
|
|
3474
|
+
userBubble: 'linear-gradient(135deg, #6366f1, #a855f7)',
|
|
3475
|
+
aiBubble: '#1e1b4b',
|
|
3476
|
+
headerGradient: 'linear-gradient(90deg, rgba(99, 102, 241, 0.15), rgba(168, 85, 247, 0.15))',
|
|
3477
|
+
border: 'rgba(99, 102, 241, 0.3)',
|
|
3478
|
+
shadow: 'rgba(0, 0, 0, 0.3)',
|
|
3479
|
+
inputBackground: '#1e1b4b',
|
|
3480
|
+
inputBorder: '#312e81',
|
|
3481
|
+
loading: '#94a3b8',
|
|
3482
|
+
success: '#34d399',
|
|
3483
|
+
error: '#f87171',
|
|
3484
|
+
warning: '#fbbf24'
|
|
3485
|
+
},
|
|
3486
|
+
borderRadius: {
|
|
3487
|
+
dialog: '18px',
|
|
3488
|
+
bubble: '14px',
|
|
3489
|
+
button: '50%',
|
|
3490
|
+
input: '30px',
|
|
3491
|
+
small: '8px',
|
|
3492
|
+
medium: '14px'
|
|
3493
|
+
},
|
|
3494
|
+
fontSize: {
|
|
3495
|
+
title: '15px',
|
|
3496
|
+
welcomeText: '17px',
|
|
3497
|
+
welcomeDesc: '13px',
|
|
3498
|
+
message: '14px',
|
|
3499
|
+
time: '11px',
|
|
3500
|
+
small: '11px'
|
|
3501
|
+
},
|
|
3502
|
+
boxShadow: {
|
|
3503
|
+
dialog: '0 0 30px rgba(99, 102, 241, 0.2), 0 8px 32px rgba(0, 0, 0, 0.4)',
|
|
3504
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.2)',
|
|
3505
|
+
userBubble: '0 4px 12px rgba(99, 102, 241, 0.3)',
|
|
3506
|
+
button: '0 4px 12px rgba(99, 102, 241, 0.4)'
|
|
3507
|
+
}
|
|
3508
|
+
};
|
|
3509
|
+
|
|
3510
|
+
/**
|
|
3511
|
+
* 日落主题(暖色调)
|
|
3512
|
+
*/
|
|
3513
|
+
const SUNSET_THEME = {
|
|
3514
|
+
name: 'sunset',
|
|
3515
|
+
label: '日落主题',
|
|
3516
|
+
colors: {
|
|
3517
|
+
primary: '#ea580c',
|
|
3518
|
+
primaryLight: '#f97316',
|
|
3519
|
+
primaryDark: '#c2410c',
|
|
3520
|
+
secondary: '#dc2626',
|
|
3521
|
+
background: '#ffffff',
|
|
3522
|
+
backgroundGradient: '#fff8f0',
|
|
3523
|
+
text: '#1e293b',
|
|
3524
|
+
textSecondary: '#64748b',
|
|
3525
|
+
userBubble: 'linear-gradient(135deg, #ea580c, #dc2626)',
|
|
3526
|
+
aiBubble: '#ffffff',
|
|
3527
|
+
headerGradient: 'linear-gradient(90deg, rgba(234, 88, 12, 0.08), rgba(220, 38, 38, 0.08))',
|
|
3528
|
+
border: 'rgba(234, 88, 12, 0.15)',
|
|
3529
|
+
shadow: 'rgba(234, 88, 12, 0.12)',
|
|
3530
|
+
inputBackground: '#fff8f0',
|
|
3531
|
+
inputBorder: '#fed7aa',
|
|
3532
|
+
loading: '#64748b',
|
|
3533
|
+
success: '#52c41a',
|
|
3534
|
+
error: '#ff4d4f',
|
|
3535
|
+
warning: '#faad14'
|
|
3536
|
+
},
|
|
3537
|
+
borderRadius: {
|
|
3538
|
+
dialog: '16px',
|
|
3539
|
+
bubble: '12px',
|
|
3540
|
+
button: '50%',
|
|
3541
|
+
input: '28px',
|
|
3542
|
+
small: '6px',
|
|
3543
|
+
medium: '12px'
|
|
3544
|
+
},
|
|
3545
|
+
fontSize: {
|
|
3546
|
+
title: '15px',
|
|
3547
|
+
welcomeText: '17px',
|
|
3548
|
+
welcomeDesc: '13px',
|
|
3549
|
+
message: '14px',
|
|
3550
|
+
time: '11px',
|
|
3551
|
+
small: '11px'
|
|
3552
|
+
},
|
|
3553
|
+
boxShadow: {
|
|
3554
|
+
dialog: '0 0 30px rgba(234, 88, 12, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
|
|
3555
|
+
bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
|
|
3556
|
+
userBubble: '0 4px 12px rgba(234, 88, 12, 0.25)',
|
|
3557
|
+
button: '0 4px 12px rgba(234, 88, 12, 0.35)'
|
|
3558
|
+
}
|
|
3559
|
+
};
|
|
3560
|
+
|
|
3561
|
+
/**
|
|
3562
|
+
* 所有预设主题列表
|
|
3563
|
+
*/
|
|
3564
|
+
const PRESET_THEMES = {
|
|
3565
|
+
DEFAULT: DEFAULT_THEME,
|
|
3566
|
+
DARK: DARK_THEME,
|
|
3567
|
+
FRESH: FRESH_THEME,
|
|
3568
|
+
VIBRANT: VIBRANT_THEME,
|
|
3569
|
+
ROMANTIC: ROMANTIC_THEME,
|
|
3570
|
+
PURPLE: PURPLE_THEME,
|
|
3571
|
+
OCEAN: OCEAN_THEME,
|
|
3572
|
+
TWILIGHT: TWILIGHT_THEME,
|
|
3573
|
+
MINT: MINT_THEME,
|
|
3574
|
+
ROSE: ROSE_THEME,
|
|
3575
|
+
AURORA: AURORA_THEME,
|
|
3576
|
+
LAVENDER: LAVENDER_THEME,
|
|
3577
|
+
CORAL: CORAL_THEME,
|
|
3578
|
+
JADE: JADE_THEME,
|
|
3579
|
+
STARSKY: STARSKY_THEME,
|
|
3580
|
+
SUNSET: SUNSET_THEME
|
|
3581
|
+
};
|
|
3582
|
+
|
|
2722
3583
|
/**
|
|
2723
3584
|
* AIChatDialog - 纯JavaScript实现的AI对话组件 (Web Components)
|
|
2724
3585
|
* 样式与功能完全对齐 Vue 版本(1:1 复刻)
|
|
2725
3586
|
*
|
|
2726
3587
|
* @author IBC AI Team
|
|
2727
|
-
* @version 2.
|
|
3588
|
+
* @version 2.0.5
|
|
2728
3589
|
*/
|
|
2729
3590
|
|
|
2730
3591
|
|
|
@@ -2773,312 +3634,6 @@ const THEME_COLOR_KEY_MAP = {
|
|
|
2773
3634
|
};
|
|
2774
3635
|
|
|
2775
3636
|
// ========== 16种预设主题(与Vue版themes.js完全一致) ==========
|
|
2776
|
-
const PRESET_THEMES = {
|
|
2777
|
-
DEFAULT: {
|
|
2778
|
-
colors: {
|
|
2779
|
-
primary: '#1890ff',
|
|
2780
|
-
primaryLight: '#40a9ff',
|
|
2781
|
-
primaryDark: '#096dd9',
|
|
2782
|
-
secondary: '#722ed1',
|
|
2783
|
-
background: '#ffffff',
|
|
2784
|
-
backgroundGradient: '#f8fafc',
|
|
2785
|
-
text: '#1e293b',
|
|
2786
|
-
textSecondary: '#64748b',
|
|
2787
|
-
userBubble: 'linear-gradient(135deg, #1890ff, #40a9ff)',
|
|
2788
|
-
aiBubble: '#ffffff',
|
|
2789
|
-
headerGradient: 'linear-gradient(90deg, rgba(24,144,255,0.08), rgba(114,46,209,0.08))',
|
|
2790
|
-
border: 'rgba(24,144,255,0.15)',
|
|
2791
|
-
shadow: 'rgba(24,144,255,0.12)',
|
|
2792
|
-
inputBackground: '#f8fafc',
|
|
2793
|
-
inputBorder: '#e2e8f0'
|
|
2794
|
-
}
|
|
2795
|
-
},
|
|
2796
|
-
DARK: {
|
|
2797
|
-
colors: {
|
|
2798
|
-
primary: '#40a9ff',
|
|
2799
|
-
primaryLight: '#69c0ff',
|
|
2800
|
-
primaryDark: '#1890ff',
|
|
2801
|
-
secondary: '#9254de',
|
|
2802
|
-
background: '#0f172a',
|
|
2803
|
-
backgroundGradient: '#1e293b',
|
|
2804
|
-
text: '#f1f5f9',
|
|
2805
|
-
textSecondary: '#94a3b8',
|
|
2806
|
-
userBubble: 'linear-gradient(135deg, #1890ff, #40a9ff)',
|
|
2807
|
-
aiBubble: '#1e293b',
|
|
2808
|
-
headerGradient: 'linear-gradient(90deg, rgba(64,169,255,0.15), rgba(146,84,222,0.15))',
|
|
2809
|
-
border: 'rgba(64,169,255,0.3)',
|
|
2810
|
-
shadow: 'rgba(0,0,0,0.3)',
|
|
2811
|
-
inputBackground: '#1e293b',
|
|
2812
|
-
inputBorder: '#334155'
|
|
2813
|
-
}
|
|
2814
|
-
},
|
|
2815
|
-
FRESH: {
|
|
2816
|
-
colors: {
|
|
2817
|
-
primary: '#52c41a',
|
|
2818
|
-
primaryLight: '#73d13d',
|
|
2819
|
-
primaryDark: '#389e0d',
|
|
2820
|
-
secondary: '#1890ff',
|
|
2821
|
-
background: '#ffffff',
|
|
2822
|
-
backgroundGradient: '#f6ffed',
|
|
2823
|
-
text: '#1e293b',
|
|
2824
|
-
textSecondary: '#64748b',
|
|
2825
|
-
userBubble: 'linear-gradient(135deg, #52c41a, #73d13d)',
|
|
2826
|
-
aiBubble: '#ffffff',
|
|
2827
|
-
headerGradient: 'linear-gradient(90deg, rgba(82,196,26,0.08), rgba(24,144,255,0.08))',
|
|
2828
|
-
border: 'rgba(82,196,26,0.15)',
|
|
2829
|
-
shadow: 'rgba(82,196,26,0.12)',
|
|
2830
|
-
inputBackground: '#f6ffed',
|
|
2831
|
-
inputBorder: '#d9f7be'
|
|
2832
|
-
}
|
|
2833
|
-
},
|
|
2834
|
-
VIBRANT: {
|
|
2835
|
-
colors: {
|
|
2836
|
-
primary: '#fa8c16',
|
|
2837
|
-
primaryLight: '#ffa940',
|
|
2838
|
-
primaryDark: '#d46b08',
|
|
2839
|
-
secondary: '#f5222d',
|
|
2840
|
-
background: '#ffffff',
|
|
2841
|
-
backgroundGradient: '#fff7e6',
|
|
2842
|
-
text: '#1e293b',
|
|
2843
|
-
textSecondary: '#64748b',
|
|
2844
|
-
userBubble: 'linear-gradient(135deg, #fa8c16, #ffa940)',
|
|
2845
|
-
aiBubble: '#ffffff',
|
|
2846
|
-
headerGradient: 'linear-gradient(90deg, rgba(250,140,22,0.08), rgba(245,34,45,0.08))',
|
|
2847
|
-
border: 'rgba(250,140,22,0.15)',
|
|
2848
|
-
shadow: 'rgba(250,140,22,0.12)',
|
|
2849
|
-
inputBackground: '#fff7e6',
|
|
2850
|
-
inputBorder: '#ffd591'
|
|
2851
|
-
}
|
|
2852
|
-
},
|
|
2853
|
-
ROMANTIC: {
|
|
2854
|
-
colors: {
|
|
2855
|
-
primary: '#eb2f96',
|
|
2856
|
-
primaryLight: '#fb6f92',
|
|
2857
|
-
primaryDark: '#c41d7f',
|
|
2858
|
-
secondary: '#722ed1',
|
|
2859
|
-
background: '#ffffff',
|
|
2860
|
-
backgroundGradient: '#fff0f6',
|
|
2861
|
-
text: '#1e293b',
|
|
2862
|
-
textSecondary: '#64748b',
|
|
2863
|
-
userBubble: 'linear-gradient(135deg, #eb2f96, #fb6f92)',
|
|
2864
|
-
aiBubble: '#ffffff',
|
|
2865
|
-
headerGradient: 'linear-gradient(90deg, rgba(235,47,150,0.08), rgba(114,46,209,0.08))',
|
|
2866
|
-
border: 'rgba(235,47,150,0.15)',
|
|
2867
|
-
shadow: 'rgba(235,47,150,0.12)',
|
|
2868
|
-
inputBackground: '#fff0f6',
|
|
2869
|
-
inputBorder: '#ffadd2'
|
|
2870
|
-
}
|
|
2871
|
-
},
|
|
2872
|
-
PURPLE: {
|
|
2873
|
-
colors: {
|
|
2874
|
-
primary: '#722ed1',
|
|
2875
|
-
primaryLight: '#9254de',
|
|
2876
|
-
primaryDark: '#531dab',
|
|
2877
|
-
secondary: '#1890ff',
|
|
2878
|
-
background: '#ffffff',
|
|
2879
|
-
backgroundGradient: '#f9f0ff',
|
|
2880
|
-
text: '#1e293b',
|
|
2881
|
-
textSecondary: '#64748b',
|
|
2882
|
-
userBubble: 'linear-gradient(135deg, #722ed1, #9254de)',
|
|
2883
|
-
aiBubble: '#ffffff',
|
|
2884
|
-
headerGradient: 'linear-gradient(90deg, rgba(114,46,209,0.08), rgba(24,144,255,0.08))',
|
|
2885
|
-
border: 'rgba(114,46,209,0.15)',
|
|
2886
|
-
shadow: 'rgba(114,46,209,0.12)',
|
|
2887
|
-
inputBackground: '#f9f0ff',
|
|
2888
|
-
inputBorder: '#d3adf7'
|
|
2889
|
-
}
|
|
2890
|
-
},
|
|
2891
|
-
OCEAN: {
|
|
2892
|
-
colors: {
|
|
2893
|
-
primary: '#0077b6',
|
|
2894
|
-
primaryLight: '#00b4d8',
|
|
2895
|
-
primaryDark: '#023e8a',
|
|
2896
|
-
secondary: '#00b4d8',
|
|
2897
|
-
background: '#ffffff',
|
|
2898
|
-
backgroundGradient: '#f0f9ff',
|
|
2899
|
-
text: '#1e293b',
|
|
2900
|
-
textSecondary: '#64748b',
|
|
2901
|
-
userBubble: 'linear-gradient(135deg, #0077b6, #00b4d8)',
|
|
2902
|
-
aiBubble: '#ffffff',
|
|
2903
|
-
headerGradient: 'linear-gradient(90deg, rgba(0,119,182,0.08), rgba(0,180,216,0.08))',
|
|
2904
|
-
border: 'rgba(0,119,182,0.15)',
|
|
2905
|
-
shadow: 'rgba(0,119,182,0.12)',
|
|
2906
|
-
inputBackground: '#f0f9ff',
|
|
2907
|
-
inputBorder: '#bae6fd'
|
|
2908
|
-
}
|
|
2909
|
-
},
|
|
2910
|
-
TWILIGHT: {
|
|
2911
|
-
colors: {
|
|
2912
|
-
primary: '#9333ea',
|
|
2913
|
-
primaryLight: '#a855f7',
|
|
2914
|
-
primaryDark: '#7e22ce',
|
|
2915
|
-
secondary: '#ec4899',
|
|
2916
|
-
background: '#ffffff',
|
|
2917
|
-
backgroundGradient: '#faf5ff',
|
|
2918
|
-
text: '#1e293b',
|
|
2919
|
-
textSecondary: '#64748b',
|
|
2920
|
-
userBubble: 'linear-gradient(135deg, #9333ea, #ec4899)',
|
|
2921
|
-
aiBubble: '#ffffff',
|
|
2922
|
-
headerGradient: 'linear-gradient(90deg, rgba(147,51,234,0.08), rgba(236,72,153,0.08))',
|
|
2923
|
-
border: 'rgba(147,51,234,0.15)',
|
|
2924
|
-
shadow: 'rgba(147,51,234,0.12)',
|
|
2925
|
-
inputBackground: '#faf5ff',
|
|
2926
|
-
inputBorder: '#e9d5ff'
|
|
2927
|
-
}
|
|
2928
|
-
},
|
|
2929
|
-
MINT: {
|
|
2930
|
-
colors: {
|
|
2931
|
-
primary: '#14b8a6',
|
|
2932
|
-
primaryLight: '#2dd4bf',
|
|
2933
|
-
primaryDark: '#0d9488',
|
|
2934
|
-
secondary: '#06b6d4',
|
|
2935
|
-
background: '#ffffff',
|
|
2936
|
-
backgroundGradient: '#f0fdfa',
|
|
2937
|
-
text: '#1e293b',
|
|
2938
|
-
textSecondary: '#64748b',
|
|
2939
|
-
userBubble: 'linear-gradient(135deg, #14b8a6, #2dd4bf)',
|
|
2940
|
-
aiBubble: '#ffffff',
|
|
2941
|
-
headerGradient: 'linear-gradient(90deg, rgba(20,184,166,0.08), rgba(6,182,212,0.08))',
|
|
2942
|
-
border: 'rgba(20,184,166,0.15)',
|
|
2943
|
-
shadow: 'rgba(20,184,166,0.12)',
|
|
2944
|
-
inputBackground: '#f0fdfa',
|
|
2945
|
-
inputBorder: '#99f6e4'
|
|
2946
|
-
}
|
|
2947
|
-
},
|
|
2948
|
-
ROSE: {
|
|
2949
|
-
colors: {
|
|
2950
|
-
primary: '#e11d48',
|
|
2951
|
-
primaryLight: '#fb7185',
|
|
2952
|
-
primaryDark: '#be123c',
|
|
2953
|
-
secondary: '#f43f5e',
|
|
2954
|
-
background: '#ffffff',
|
|
2955
|
-
backgroundGradient: '#fff1f2',
|
|
2956
|
-
text: '#1e293b',
|
|
2957
|
-
textSecondary: '#64748b',
|
|
2958
|
-
userBubble: 'linear-gradient(135deg, #e11d48, #fb7185)',
|
|
2959
|
-
aiBubble: '#ffffff',
|
|
2960
|
-
headerGradient: 'linear-gradient(90deg, rgba(225,29,72,0.08), rgba(244,63,94,0.08))',
|
|
2961
|
-
border: 'rgba(225,29,72,0.15)',
|
|
2962
|
-
shadow: 'rgba(225,29,72,0.12)',
|
|
2963
|
-
inputBackground: '#fff1f2',
|
|
2964
|
-
inputBorder: '#fecdd3'
|
|
2965
|
-
}
|
|
2966
|
-
},
|
|
2967
|
-
AURORA: {
|
|
2968
|
-
colors: {
|
|
2969
|
-
primary: '#0ea5e9',
|
|
2970
|
-
primaryLight: '#38bdf8',
|
|
2971
|
-
primaryDark: '#0284c7',
|
|
2972
|
-
secondary: '#10b981',
|
|
2973
|
-
background: '#ffffff',
|
|
2974
|
-
backgroundGradient: '#f0f9ff',
|
|
2975
|
-
text: '#1e293b',
|
|
2976
|
-
textSecondary: '#64748b',
|
|
2977
|
-
userBubble: 'linear-gradient(135deg, #0ea5e9, #10b981)',
|
|
2978
|
-
aiBubble: '#ffffff',
|
|
2979
|
-
headerGradient: 'linear-gradient(90deg, rgba(14,165,233,0.08), rgba(16,185,129,0.08))',
|
|
2980
|
-
border: 'rgba(14,165,233,0.15)',
|
|
2981
|
-
shadow: 'rgba(14,165,233,0.12)',
|
|
2982
|
-
inputBackground: '#f0f9ff',
|
|
2983
|
-
inputBorder: '#bae6fd'
|
|
2984
|
-
}
|
|
2985
|
-
},
|
|
2986
|
-
LAVENDER: {
|
|
2987
|
-
colors: {
|
|
2988
|
-
primary: '#8b5cf6',
|
|
2989
|
-
primaryLight: '#a78bfa',
|
|
2990
|
-
primaryDark: '#7c3aed',
|
|
2991
|
-
secondary: '#c084fc',
|
|
2992
|
-
background: '#ffffff',
|
|
2993
|
-
backgroundGradient: '#faf5ff',
|
|
2994
|
-
text: '#1e293b',
|
|
2995
|
-
textSecondary: '#64748b',
|
|
2996
|
-
userBubble: 'linear-gradient(135deg, #8b5cf6, #c084fc)',
|
|
2997
|
-
aiBubble: '#ffffff',
|
|
2998
|
-
headerGradient: 'linear-gradient(90deg, rgba(139,92,246,0.08), rgba(192,132,252,0.08))',
|
|
2999
|
-
border: 'rgba(139,92,246,0.15)',
|
|
3000
|
-
shadow: 'rgba(139,92,246,0.12)',
|
|
3001
|
-
inputBackground: '#faf5ff',
|
|
3002
|
-
inputBorder: '#ddd6fe'
|
|
3003
|
-
}
|
|
3004
|
-
},
|
|
3005
|
-
CORAL: {
|
|
3006
|
-
colors: {
|
|
3007
|
-
primary: '#f97316',
|
|
3008
|
-
primaryLight: '#fb923c',
|
|
3009
|
-
primaryDark: '#ea580c',
|
|
3010
|
-
secondary: '#f43f5e',
|
|
3011
|
-
background: '#ffffff',
|
|
3012
|
-
backgroundGradient: '#fff7ed',
|
|
3013
|
-
text: '#1e293b',
|
|
3014
|
-
textSecondary: '#64748b',
|
|
3015
|
-
userBubble: 'linear-gradient(135deg, #f97316, #fb923c)',
|
|
3016
|
-
aiBubble: '#ffffff',
|
|
3017
|
-
headerGradient: 'linear-gradient(90deg, rgba(249,115,22,0.08), rgba(244,63,94,0.08))',
|
|
3018
|
-
border: 'rgba(249,115,22,0.15)',
|
|
3019
|
-
shadow: 'rgba(249,115,22,0.12)',
|
|
3020
|
-
inputBackground: '#fff7ed',
|
|
3021
|
-
inputBorder: '#fed7aa'
|
|
3022
|
-
}
|
|
3023
|
-
},
|
|
3024
|
-
JADE: {
|
|
3025
|
-
colors: {
|
|
3026
|
-
primary: '#059669',
|
|
3027
|
-
primaryLight: '#10b981',
|
|
3028
|
-
primaryDark: '#047857',
|
|
3029
|
-
secondary: '#34d399',
|
|
3030
|
-
background: '#ffffff',
|
|
3031
|
-
backgroundGradient: '#f0fdf4',
|
|
3032
|
-
text: '#1e293b',
|
|
3033
|
-
textSecondary: '#64748b',
|
|
3034
|
-
userBubble: 'linear-gradient(135deg, #059669, #10b981)',
|
|
3035
|
-
aiBubble: '#ffffff',
|
|
3036
|
-
headerGradient: 'linear-gradient(90deg, rgba(5,150,105,0.08), rgba(52,211,153,0.08))',
|
|
3037
|
-
border: 'rgba(5,150,105,0.15)',
|
|
3038
|
-
shadow: 'rgba(5,150,105,0.12)',
|
|
3039
|
-
inputBackground: '#f0fdf4',
|
|
3040
|
-
inputBorder: '#bbf7d0'
|
|
3041
|
-
}
|
|
3042
|
-
},
|
|
3043
|
-
STARSKY: {
|
|
3044
|
-
colors: {
|
|
3045
|
-
primary: '#6366f1',
|
|
3046
|
-
primaryLight: '#818cf8',
|
|
3047
|
-
primaryDark: '#4f46e5',
|
|
3048
|
-
secondary: '#a855f7',
|
|
3049
|
-
background: '#0f172a',
|
|
3050
|
-
backgroundGradient: '#1e1b4b',
|
|
3051
|
-
text: '#e2e8f0',
|
|
3052
|
-
textSecondary: '#94a3b8',
|
|
3053
|
-
userBubble: 'linear-gradient(135deg, #6366f1, #a855f7)',
|
|
3054
|
-
aiBubble: '#1e1b4b',
|
|
3055
|
-
headerGradient: 'linear-gradient(90deg, rgba(99,102,241,0.15), rgba(168,85,247,0.15))',
|
|
3056
|
-
border: 'rgba(99,102,241,0.3)',
|
|
3057
|
-
shadow: 'rgba(0,0,0,0.3)',
|
|
3058
|
-
inputBackground: '#1e1b4b',
|
|
3059
|
-
inputBorder: '#312e81'
|
|
3060
|
-
}
|
|
3061
|
-
},
|
|
3062
|
-
SUNSET: {
|
|
3063
|
-
colors: {
|
|
3064
|
-
primary: '#ea580c',
|
|
3065
|
-
primaryLight: '#f97316',
|
|
3066
|
-
primaryDark: '#c2410c',
|
|
3067
|
-
secondary: '#dc2626',
|
|
3068
|
-
background: '#ffffff',
|
|
3069
|
-
backgroundGradient: '#fff8f0',
|
|
3070
|
-
text: '#1e293b',
|
|
3071
|
-
textSecondary: '#64748b',
|
|
3072
|
-
userBubble: 'linear-gradient(135deg, #ea580c, #dc2626)',
|
|
3073
|
-
aiBubble: '#ffffff',
|
|
3074
|
-
headerGradient: 'linear-gradient(90deg, rgba(234,88,12,0.08), rgba(220,38,38,0.08))',
|
|
3075
|
-
border: 'rgba(234,88,12,0.15)',
|
|
3076
|
-
shadow: 'rgba(234,88,12,0.12)',
|
|
3077
|
-
inputBackground: '#fff8f0',
|
|
3078
|
-
inputBorder: '#fed7aa'
|
|
3079
|
-
}
|
|
3080
|
-
}
|
|
3081
|
-
};
|
|
3082
3637
|
class AIChatDialog extends HTMLElement {
|
|
3083
3638
|
static get observedAttributes() {
|
|
3084
3639
|
return ['visible'];
|
|
@@ -3121,6 +3676,8 @@ class AIChatDialog extends HTMLElement {
|
|
|
3121
3676
|
this._runtimeEventsContainerEl = null;
|
|
3122
3677
|
this._runtimeStatusEl = null;
|
|
3123
3678
|
this._runtimeCountEl = null;
|
|
3679
|
+
// P3: 页面上下文数据(宿主页面选中的数据)
|
|
3680
|
+
this._context = {};
|
|
3124
3681
|
|
|
3125
3682
|
// ====== 默认主题配置(与 themes.js DEFAULT_THEME 完全一致) ======
|
|
3126
3683
|
this._themeVars = {
|
|
@@ -3207,6 +3764,8 @@ class AIChatDialog extends HTMLElement {
|
|
|
3207
3764
|
if (this._handleOffline) window.removeEventListener('offline', this._handleOffline);
|
|
3208
3765
|
// P2-17: 清理resize监听
|
|
3209
3766
|
if (this._handleResize) window.removeEventListener('resize', this._handleResize);
|
|
3767
|
+
// P0: 清理拖拽事件监听
|
|
3768
|
+
this._cleanupDragListeners();
|
|
3210
3769
|
// 暂停后台Token刷新定时器(detach时停止,re-attach时由connectedCallback恢复)
|
|
3211
3770
|
if (this._chatClient) {
|
|
3212
3771
|
this._chatClient.stopBackgroundRefresh();
|
|
@@ -3249,6 +3808,8 @@ class AIChatDialog extends HTMLElement {
|
|
|
3249
3808
|
// P2-17: 应用移动端/桌面端布局(自动全屏或恢复浮动气泡)
|
|
3250
3809
|
_applyMobileLayout() {
|
|
3251
3810
|
if (!this._dialog) return;
|
|
3811
|
+
// 行内嵌入模式跳过,保持 CSS 控制的布局
|
|
3812
|
+
if (this.getAttribute('mode') === 'inline') return;
|
|
3252
3813
|
if (this._isMobile) {
|
|
3253
3814
|
// 移动端:强制全屏(与Vue版 dialogStyle 一致)
|
|
3254
3815
|
this._dialog.style.width = '100vw';
|
|
@@ -3356,6 +3917,14 @@ class AIChatDialog extends HTMLElement {
|
|
|
3356
3917
|
authFn: null,
|
|
3357
3918
|
onLoad: null,
|
|
3358
3919
|
onError: null,
|
|
3920
|
+
// P3: 发送前回调 - 每发消息前调用,可返回最新页面上下文(与 setContext 合并,此回调结果优先)
|
|
3921
|
+
onBeforeSend: null,
|
|
3922
|
+
// P3: 上下文注入方式 — 'prompt'=拼到用户消息前面(默认), 'bizParams'=注入到 bizParams JSON 中
|
|
3923
|
+
contextMode: 'prompt',
|
|
3924
|
+
// P4: 调试模式 - 开启后 console 打印请求/响应/SSE/上下文合并全过程
|
|
3925
|
+
debug: false,
|
|
3926
|
+
// P4: 自定义消息操作按钮 — 返回数组 [{label, className?, onClick}] 在 AI 消息下方渲染
|
|
3927
|
+
onMessageActions: null,
|
|
3359
3928
|
suggestions: [{
|
|
3360
3929
|
label: '帮我购买一台轻量应用服务器用于部署应用',
|
|
3361
3930
|
value: '帮我购买一台轻量应用服务器用于部署应用'
|
|
@@ -3369,6 +3938,11 @@ class AIChatDialog extends HTMLElement {
|
|
|
3369
3938
|
this._chatClient = new AIChatClient(this._config);
|
|
3370
3939
|
if (this._conversationId) this._chatClient.setConversationId(this._conversationId);
|
|
3371
3940
|
this.applyConfig();
|
|
3941
|
+
// P1-2 fix: 在 _config 就绪后初始化拖拽,以正确读取 enableDrag
|
|
3942
|
+
if (this._config?.enableDrag !== false && this.getAttribute('mode') !== 'inline' && !this._dragInitialized) {
|
|
3943
|
+
this.initDraggable();
|
|
3944
|
+
}
|
|
3945
|
+
this._debugLog('初始化完成', 'appId=' + this._config.appId, 'userId=' + this._config.userId, 'baseUrl=' + this._config.apiBaseUrl, 'debug=' + !!this._config.debug, 'contextMode=' + (this._config.contextMode || 'prompt'));
|
|
3372
3946
|
this.loadAppDetail();
|
|
3373
3947
|
// 触发 onLoad 回调(与Vue版一致)
|
|
3374
3948
|
if (this._config?.onLoad) this._config.onLoad(this);
|
|
@@ -3455,6 +4029,44 @@ class AIChatDialog extends HTMLElement {
|
|
|
3455
4029
|
return this;
|
|
3456
4030
|
}
|
|
3457
4031
|
|
|
4032
|
+
/**
|
|
4033
|
+
* 设置页面上下文数据(宿主页面选中的数据,随每次请求发送)
|
|
4034
|
+
* @param {Object} context - 上下文数据对象,传 null 清空
|
|
4035
|
+
* @returns {this}
|
|
4036
|
+
*/
|
|
4037
|
+
setContext(context) {
|
|
4038
|
+
this._context = context && typeof context === 'object' ? {
|
|
4039
|
+
...context
|
|
4040
|
+
} : {};
|
|
4041
|
+
return this;
|
|
4042
|
+
}
|
|
4043
|
+
|
|
4044
|
+
/**
|
|
4045
|
+
* 获取当前上下文数据
|
|
4046
|
+
* @returns {Object}
|
|
4047
|
+
*/
|
|
4048
|
+
getContext() {
|
|
4049
|
+
return {
|
|
4050
|
+
...this._context
|
|
4051
|
+
};
|
|
4052
|
+
}
|
|
4053
|
+
|
|
4054
|
+
/**
|
|
4055
|
+
* 外部触发表态发送(业务层主动调用,如点击外部按钮触发 AI 请求)
|
|
4056
|
+
* @param {string} text - 要发送的消息内容
|
|
4057
|
+
* @returns {this}
|
|
4058
|
+
*/
|
|
4059
|
+
send(text) {
|
|
4060
|
+
const content = String(text || '').trim();
|
|
4061
|
+
if (!content) return this;
|
|
4062
|
+
if (this._input) this._input.value = content;
|
|
4063
|
+
this._autoResizeInput();
|
|
4064
|
+
this._updateSendButtonState();
|
|
4065
|
+
this._lastSendTime = 0; // 跳过防抖,外部触发视为独立操作
|
|
4066
|
+
this.handleSend();
|
|
4067
|
+
return this;
|
|
4068
|
+
}
|
|
4069
|
+
|
|
3458
4070
|
// ==================== 显示/隐藏 ====================
|
|
3459
4071
|
|
|
3460
4072
|
showDialog() {
|
|
@@ -3510,11 +4122,11 @@ class AIChatDialog extends HTMLElement {
|
|
|
3510
4122
|
/* ====== 对话框主体(与Vue .ai-chat-dialog 完全一致) ====== */
|
|
3511
4123
|
.ai-chat-dialog {
|
|
3512
4124
|
position: fixed;
|
|
3513
|
-
top: 96px;
|
|
3514
|
-
right: 24px;
|
|
4125
|
+
top: var(--ai-dialog-top, 96px);
|
|
4126
|
+
right: var(--ai-dialog-right, 24px);
|
|
3515
4127
|
bottom: auto;
|
|
3516
|
-
width: min(420px, calc(100vw - 48px));
|
|
3517
|
-
height: min(640px, 80vh);
|
|
4128
|
+
width: var(--ai-dialog-width, min(420px, calc(100vw - 48px)));
|
|
4129
|
+
height: var(--ai-dialog-height, min(640px, 80vh));
|
|
3518
4130
|
background: var(--ai-bg);
|
|
3519
4131
|
border-radius: 16px;
|
|
3520
4132
|
border: 1px solid rgba(226, 232, 240, 0.78);
|
|
@@ -4090,6 +4702,19 @@ class AIChatDialog extends HTMLElement {
|
|
|
4090
4702
|
color: var(--ai-success);
|
|
4091
4703
|
background: rgba(16, 185, 129, 0.08);
|
|
4092
4704
|
}
|
|
4705
|
+
/* P4: 自定义操作按钮(文本标签型,宽度自适应) */
|
|
4706
|
+
.action-icon.custom-action-btn {
|
|
4707
|
+
width: auto;
|
|
4708
|
+
padding: 4px 10px;
|
|
4709
|
+
font-size: 12px;
|
|
4710
|
+
font-weight: 500;
|
|
4711
|
+
white-space: nowrap;
|
|
4712
|
+
}
|
|
4713
|
+
.action-icon.custom-action-btn:hover {
|
|
4714
|
+
color: #fff;
|
|
4715
|
+
background: var(--ai-primary);
|
|
4716
|
+
transform: translateY(-1px);
|
|
4717
|
+
}
|
|
4093
4718
|
|
|
4094
4719
|
/* ========== 底部输入框(与Vue .dialog-footer 一致) ========== */
|
|
4095
4720
|
.dialog-footer {
|
|
@@ -4504,6 +5129,27 @@ class AIChatDialog extends HTMLElement {
|
|
|
4504
5129
|
.action-icon { width: 30px; height: 30px; }
|
|
4505
5130
|
}
|
|
4506
5131
|
|
|
5132
|
+
/* ========== 行内嵌入模式(mode="inline",挂载到用户指定容器) ========== */
|
|
5133
|
+
:host([mode="inline"]) { position: relative; top: auto; right: auto; bottom: auto; z-index: auto; width: 100%; height: 100%; }
|
|
5134
|
+
:host([mode="inline"]) .ai-float-container { height: 100%; }
|
|
5135
|
+
:host([mode="inline"]) .float-button { display: none; }
|
|
5136
|
+
:host([mode="inline"]) .ai-chat-dialog {
|
|
5137
|
+
position: relative;
|
|
5138
|
+
top: auto;
|
|
5139
|
+
right: auto;
|
|
5140
|
+
width: 100%;
|
|
5141
|
+
height: 100%;
|
|
5142
|
+
border-radius: 0;
|
|
5143
|
+
box-shadow: none;
|
|
5144
|
+
border: 1px solid var(--ai-border);
|
|
5145
|
+
opacity: 1;
|
|
5146
|
+
transform: none;
|
|
5147
|
+
pointer-events: auto;
|
|
5148
|
+
}
|
|
5149
|
+
:host([mode="inline"]) .dialog-header { cursor: default; }
|
|
5150
|
+
:host([mode="inline"]) .close-btn,
|
|
5151
|
+
:host([mode="inline"]) .expand-btn { display: none; }
|
|
5152
|
+
|
|
4507
5153
|
/* ========== 暗色主题覆盖(theme: 'dark') ========== */
|
|
4508
5154
|
:host(.dark-theme) .ai-chat-dialog {
|
|
4509
5155
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
@@ -4649,8 +5295,8 @@ class AIChatDialog extends HTMLElement {
|
|
|
4649
5295
|
});
|
|
4650
5296
|
}
|
|
4651
5297
|
|
|
4652
|
-
//
|
|
4653
|
-
|
|
5298
|
+
// 拖拽(内嵌模式禁用)— 由 init() 在 _config 就绪后触发
|
|
5299
|
+
// initDraggable 延迟到 init() 中执行以免 _config 为空
|
|
4654
5300
|
});
|
|
4655
5301
|
}
|
|
4656
5302
|
|
|
@@ -4703,59 +5349,97 @@ class AIChatDialog extends HTMLElement {
|
|
|
4703
5349
|
initDraggable() {
|
|
4704
5350
|
const header = this.shadowRoot?.querySelector('.dialog-header');
|
|
4705
5351
|
if (!header) return;
|
|
5352
|
+
|
|
5353
|
+
// 清理上一次遗留的 document 级监听(SPA 路由切换场景)
|
|
5354
|
+
this._cleanupDragListeners();
|
|
5355
|
+
const self = this;
|
|
4706
5356
|
const startDrag = (clientX, clientY) => {
|
|
4707
5357
|
// P2-17: 移动端禁用拖拽(与Vue版 startTouchDrag: if(isExpanded || isMobile) return 一致)
|
|
4708
|
-
if (
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
const rect =
|
|
4712
|
-
|
|
4713
|
-
|
|
5358
|
+
if (self._isExpanded || self._isMobile) return;
|
|
5359
|
+
self._isDragging = true;
|
|
5360
|
+
self._dialog.classList.add('dragging');
|
|
5361
|
+
const rect = self._dialog.getBoundingClientRect();
|
|
5362
|
+
self._dragStartX = clientX - rect.left;
|
|
5363
|
+
self._dragStartY = clientY - rect.top;
|
|
4714
5364
|
};
|
|
4715
5365
|
const onDrag = (clientX, clientY) => {
|
|
4716
|
-
if (!
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
5366
|
+
if (!self._isDragging) return;
|
|
5367
|
+
self._dialogX = clientX - self._dragStartX;
|
|
5368
|
+
self._dialogY = clientY - self._dragStartY;
|
|
5369
|
+
self._dialog.style.left = self._dialogX + 'px';
|
|
5370
|
+
self._dialog.style.right = 'auto';
|
|
5371
|
+
self._dialog.style.top = self._dialogY + 'px';
|
|
5372
|
+
self._dialog.style.bottom = 'auto';
|
|
4723
5373
|
};
|
|
4724
5374
|
const stopDrag = () => {
|
|
4725
|
-
if (
|
|
4726
|
-
|
|
4727
|
-
|
|
5375
|
+
if (self._isDragging) {
|
|
5376
|
+
self._isDragging = false;
|
|
5377
|
+
self._dialog.classList.remove('dragging');
|
|
4728
5378
|
}
|
|
4729
5379
|
};
|
|
4730
5380
|
|
|
4731
|
-
//
|
|
4732
|
-
|
|
5381
|
+
// 鼠标事件(桌面端)— 保存引用以便清理
|
|
5382
|
+
this._dragMouseDownHandler = e => {
|
|
4733
5383
|
if (e.target.closest('button, .header-icon')) return;
|
|
4734
5384
|
startDrag(e.clientX, e.clientY);
|
|
4735
5385
|
e.preventDefault();
|
|
4736
|
-
}
|
|
4737
|
-
|
|
5386
|
+
};
|
|
5387
|
+
this._dragMouseMoveHandler = e => {
|
|
4738
5388
|
onDrag(e.clientX, e.clientY);
|
|
4739
|
-
}
|
|
4740
|
-
|
|
5389
|
+
};
|
|
5390
|
+
this._dragMouseUpHandler = stopDrag;
|
|
5391
|
+
header.addEventListener('mousedown', this._dragMouseDownHandler);
|
|
5392
|
+
document.addEventListener('mousemove', this._dragMouseMoveHandler);
|
|
5393
|
+
document.addEventListener('mouseup', this._dragMouseUpHandler);
|
|
4741
5394
|
|
|
4742
5395
|
// P1-7: 触摸事件(移动端,与Vue版一致)
|
|
4743
|
-
|
|
4744
|
-
if (
|
|
5396
|
+
this._dragTouchStartHandler = e => {
|
|
5397
|
+
if (self._isExpanded) return;
|
|
4745
5398
|
if (e.target.closest('button, .header-icon')) return;
|
|
4746
5399
|
const touch = e.touches[0];
|
|
4747
5400
|
startDrag(touch.clientX, touch.clientY);
|
|
4748
|
-
}
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
document.addEventListener('touchmove', e => {
|
|
4752
|
-
if (!this._isDragging) return;
|
|
5401
|
+
};
|
|
5402
|
+
this._dragTouchMoveHandler = e => {
|
|
5403
|
+
if (!self._isDragging) return;
|
|
4753
5404
|
const touch = e.touches[0];
|
|
4754
5405
|
onDrag(touch.clientX, touch.clientY);
|
|
4755
|
-
}
|
|
5406
|
+
};
|
|
5407
|
+
this._dragTouchEndHandler = stopDrag;
|
|
5408
|
+
header.addEventListener('touchstart', this._dragTouchStartHandler, {
|
|
5409
|
+
passive: true
|
|
5410
|
+
});
|
|
5411
|
+
document.addEventListener('touchmove', this._dragTouchMoveHandler, {
|
|
4756
5412
|
passive: true
|
|
4757
5413
|
});
|
|
4758
|
-
document.addEventListener('touchend',
|
|
5414
|
+
document.addEventListener('touchend', this._dragTouchEndHandler);
|
|
5415
|
+
this._dragInitialized = true;
|
|
5416
|
+
}
|
|
5417
|
+
|
|
5418
|
+
// P0: 清理拖拽事件监听(SPA disconnectedCallback / re-init 调用)
|
|
5419
|
+
_cleanupDragListeners() {
|
|
5420
|
+
if (this._dragMouseDownHandler) {
|
|
5421
|
+
const header = this.shadowRoot?.querySelector('.dialog-header');
|
|
5422
|
+
if (header) {
|
|
5423
|
+
header.removeEventListener('mousedown', this._dragMouseDownHandler);
|
|
5424
|
+
header.removeEventListener('touchstart', this._dragTouchStartHandler, {
|
|
5425
|
+
passive: true
|
|
5426
|
+
});
|
|
5427
|
+
}
|
|
5428
|
+
this._dragMouseDownHandler = null;
|
|
5429
|
+
this._dragTouchStartHandler = null;
|
|
5430
|
+
}
|
|
5431
|
+
if (this._dragMouseMoveHandler) {
|
|
5432
|
+
document.removeEventListener('mousemove', this._dragMouseMoveHandler);
|
|
5433
|
+
document.removeEventListener('touchmove', this._dragTouchMoveHandler, {
|
|
5434
|
+
passive: true
|
|
5435
|
+
});
|
|
5436
|
+
document.removeEventListener('mouseup', this._dragMouseUpHandler);
|
|
5437
|
+
document.removeEventListener('touchend', this._dragTouchEndHandler);
|
|
5438
|
+
this._dragMouseMoveHandler = null;
|
|
5439
|
+
this._dragTouchMoveHandler = null;
|
|
5440
|
+
this._dragMouseUpHandler = null;
|
|
5441
|
+
this._dragTouchEndHandler = null;
|
|
5442
|
+
}
|
|
4759
5443
|
}
|
|
4760
5444
|
applyConfig() {
|
|
4761
5445
|
if (!this._config) return;
|
|
@@ -4920,11 +5604,12 @@ class AIChatDialog extends HTMLElement {
|
|
|
4920
5604
|
<div class="message-content">
|
|
4921
5605
|
${hasRuntimeEvents ? this._buildRuntimePanel(msg, idx) : ''}
|
|
4922
5606
|
${bubbleContent ? `<div class="${bubbleClass}">${bubbleContent}</div>` : ''}
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
5607
|
+
${!msg._isStreaming ? `<div class="message-actions-bar">
|
|
5608
|
+
${msg.type === 'ai' ? `<div class="action-icons">
|
|
5609
|
+
<span class="action-icon copy-btn${msg.copied ? ' copied' : ''}" data-idx="${idx}" title="${msg.copied ? '已复制' : '复制'}">${msg.copied ? '<svg viewBox="0 0 24 24" fill="none" stroke-width="2"><path d="m20 6-11 11-5-5"/></svg>' : '<svg viewBox="0 0 24 24" fill="none" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>'}</span>
|
|
5610
|
+
<span class="action-icon regenerate-btn" data-idx="${idx}" title="重新回答"><svg viewBox="0 0 24 24" fill="none" stroke-width="2"><path d="M21 12a9 9 0 1 1-2.64-6.36"/><path d="M21 3v6h-6"/></svg></span>
|
|
5611
|
+
${this._buildCustomActions(msg, idx)}
|
|
5612
|
+
</div>` : ''}
|
|
4928
5613
|
</div>` : ''}
|
|
4929
5614
|
</div>
|
|
4930
5615
|
</div>`;
|
|
@@ -4954,6 +5639,24 @@ class AIChatDialog extends HTMLElement {
|
|
|
4954
5639
|
});
|
|
4955
5640
|
});
|
|
4956
5641
|
|
|
5642
|
+
// P4: 绑定自定义操作按钮
|
|
5643
|
+
this._body.querySelectorAll('.custom-action-btn').forEach(btn => {
|
|
5644
|
+
btn.addEventListener('click', () => {
|
|
5645
|
+
const idx = parseInt(btn.dataset.idx);
|
|
5646
|
+
const actionIdx = parseInt(btn.dataset.action);
|
|
5647
|
+
const msg = this._messages[idx];
|
|
5648
|
+
if (!msg) return;
|
|
5649
|
+
try {
|
|
5650
|
+
const actions = this._getCustomActions(msg, idx);
|
|
5651
|
+
if (actions && actions[actionIdx]) {
|
|
5652
|
+
actions[actionIdx].onClick(msg.content);
|
|
5653
|
+
}
|
|
5654
|
+
} catch (e) {
|
|
5655
|
+
console.warn('[AIChatDialog] 自定义操作按钮执行失败:', e);
|
|
5656
|
+
}
|
|
5657
|
+
});
|
|
5658
|
+
});
|
|
5659
|
+
|
|
4957
5660
|
// 绑定执行过程面板折叠/展开(Shadow DOM 下 inline onclick 不可靠)
|
|
4958
5661
|
this._body.querySelectorAll('.runtime-header').forEach(header => {
|
|
4959
5662
|
header.addEventListener('click', () => {
|
|
@@ -5206,7 +5909,7 @@ class AIChatDialog extends HTMLElement {
|
|
|
5206
5909
|
this.showToast(this._config?.emptyMessageError || '请输入消息内容');
|
|
5207
5910
|
return;
|
|
5208
5911
|
}
|
|
5209
|
-
if (this._isLoading) return;
|
|
5912
|
+
if (this._isLoading || this._streaming) return;
|
|
5210
5913
|
|
|
5211
5914
|
// P1-11: 字数限制检查
|
|
5212
5915
|
const maxLen = this._config?.maxLength ?? 500;
|
|
@@ -5251,10 +5954,59 @@ class AIChatDialog extends HTMLElement {
|
|
|
5251
5954
|
}));
|
|
5252
5955
|
this.setLoading(true);
|
|
5253
5956
|
try {
|
|
5957
|
+
// 上传附件并收集 attachmentId
|
|
5958
|
+
const attachmentIds = [];
|
|
5254
5959
|
for (const file of attachments) {
|
|
5255
|
-
await this.uploadAttachment(file).catch(err =>
|
|
5960
|
+
const res = await this.uploadAttachment(file).catch(err => {
|
|
5961
|
+
console.warn('[AIChatDialog] 附件上传失败:', err);
|
|
5962
|
+
return null;
|
|
5963
|
+
});
|
|
5964
|
+
if (res?.success && res.data?.attachmentId) {
|
|
5965
|
+
attachmentIds.push(res.data.attachmentId);
|
|
5966
|
+
}
|
|
5967
|
+
}
|
|
5968
|
+
|
|
5969
|
+
// P3: 收集页面上下文(setContext + onBeforeSend)
|
|
5970
|
+
let context = {
|
|
5971
|
+
...(this._context || {})
|
|
5972
|
+
};
|
|
5973
|
+
if (typeof this._config?.onBeforeSend === 'function') {
|
|
5974
|
+
try {
|
|
5975
|
+
const dynamicCtx = await this._config.onBeforeSend();
|
|
5976
|
+
if (dynamicCtx && typeof dynamicCtx === 'object') {
|
|
5977
|
+
context = {
|
|
5978
|
+
...context,
|
|
5979
|
+
...dynamicCtx
|
|
5980
|
+
};
|
|
5981
|
+
}
|
|
5982
|
+
} catch (e) {
|
|
5983
|
+
console.warn('[AIChatDialog] onBeforeSend 执行失败:', e);
|
|
5984
|
+
}
|
|
5985
|
+
}
|
|
5986
|
+
const hasContext = context && Object.keys(context).length > 0;
|
|
5987
|
+
const rawMode = this._config?.contextMode;
|
|
5988
|
+
const VALID_CONTEXT_MODES = ['prompt', 'bizParams'];
|
|
5989
|
+
const contextMode = VALID_CONTEXT_MODES.includes(rawMode) ? rawMode : rawMode ? (console.warn('[AIChatDialog] 无效的 contextMode: "' + rawMode + '",已回退为 "prompt"(有效值: ' + VALID_CONTEXT_MODES.join(', ') + ')'), 'prompt') : 'prompt';
|
|
5990
|
+
let finalPrompt = content || attachmentText;
|
|
5991
|
+
let contextForBizParams = null;
|
|
5992
|
+
if (hasContext) {
|
|
5993
|
+
this._debugLog('上下文合并', 'keys=', Object.keys(context), 'mode=', contextMode);
|
|
5994
|
+
if (contextMode === 'bizParams') {
|
|
5995
|
+
// 注入到 bizParams
|
|
5996
|
+
contextForBizParams = context;
|
|
5997
|
+
} else {
|
|
5998
|
+
// 默认:拼到 prompt 前面
|
|
5999
|
+
const ctxText = this._formatContextText(context);
|
|
6000
|
+
if (ctxText) {
|
|
6001
|
+
finalPrompt = ctxText + '\n---\n' + finalPrompt;
|
|
6002
|
+
}
|
|
6003
|
+
}
|
|
5256
6004
|
}
|
|
5257
|
-
|
|
6005
|
+
this._debugLog('发送', 'prompt=' + (finalPrompt || '').substring(0, 150) + (finalPrompt && finalPrompt.length > 150 ? '...' : ''), 'ctxKeys=' + Object.keys(contextForBizParams || context || {}).join(','), 'mode=' + contextMode);
|
|
6006
|
+
await this.sendMessageToAI(finalPrompt, {
|
|
6007
|
+
attachmentIds,
|
|
6008
|
+
context: contextForBizParams
|
|
6009
|
+
});
|
|
5258
6010
|
} catch (err) {
|
|
5259
6011
|
console.error('[AIChatDialog] Error:', err);
|
|
5260
6012
|
this.handleError(err);
|
|
@@ -5283,7 +6035,12 @@ class AIChatDialog extends HTMLElement {
|
|
|
5283
6035
|
this._streaming = true;
|
|
5284
6036
|
this.setLoading(false); // 关掉全局 loading,用消息级 loading 替代
|
|
5285
6037
|
this.updateLoadingUI(); // re-lock input via _streaming flag
|
|
5286
|
-
|
|
6038
|
+
const streamOpts = {
|
|
6039
|
+
...(options.streamOptions || {})
|
|
6040
|
+
};
|
|
6041
|
+
if (options.attachmentIds?.length) streamOpts.attachmentIds = options.attachmentIds;
|
|
6042
|
+
if (options.context) streamOpts.context = options.context;
|
|
6043
|
+
await this._directApiCallStream(msgId, content, streamOpts);
|
|
5287
6044
|
}
|
|
5288
6045
|
}
|
|
5289
6046
|
async mockResponse(userContent) {
|
|
@@ -5340,6 +6097,10 @@ class AIChatDialog extends HTMLElement {
|
|
|
5340
6097
|
if (!this._chatClient) {
|
|
5341
6098
|
this._chatClient = new AIChatClient(this._config || {});
|
|
5342
6099
|
}
|
|
6100
|
+
if (this._config?.debug) {
|
|
6101
|
+
this._chatClient.config.debug = true;
|
|
6102
|
+
}
|
|
6103
|
+
this._debugLog('Stream开始', 'msgId=' + msgId, 'content=' + (content || '').substring(0, 80), 'opts=' + JSON.stringify(requestOptions));
|
|
5343
6104
|
if (Object.prototype.hasOwnProperty.call(requestOptions, 'conversationId')) {
|
|
5344
6105
|
this._chatClient.setConversationId(requestOptions.conversationId || null);
|
|
5345
6106
|
} else if (this._conversationId) {
|
|
@@ -5458,6 +6219,7 @@ class AIChatDialog extends HTMLElement {
|
|
|
5458
6219
|
}
|
|
5459
6220
|
}, requestOptions);
|
|
5460
6221
|
if (response?.success) {
|
|
6222
|
+
this._debugLog('Stream完成', 'ok, conversationId=' + (response.data?.conversationId || this._conversationId), 'textLen=' + streamText.length);
|
|
5461
6223
|
if (response.data?.conversationId) {
|
|
5462
6224
|
this._conversationId = response.data.conversationId;
|
|
5463
6225
|
} else if (this._chatClient.conversationId) {
|
|
@@ -5470,6 +6232,7 @@ class AIChatDialog extends HTMLElement {
|
|
|
5470
6232
|
streamText = result;
|
|
5471
6233
|
}
|
|
5472
6234
|
} else {
|
|
6235
|
+
this._finalizeMsg(msgId, streamText || '(无回复)');
|
|
5473
6236
|
return;
|
|
5474
6237
|
}
|
|
5475
6238
|
this._finalizeMsg(msgId, streamText || '(无回复)');
|
|
@@ -5480,12 +6243,14 @@ class AIChatDialog extends HTMLElement {
|
|
|
5480
6243
|
}));
|
|
5481
6244
|
if (this._config?.onMessageReceived) this._config.onMessageReceived(streamText);
|
|
5482
6245
|
} catch (e) {
|
|
6246
|
+
this._debugWarn('Stream异常', e.name + ': ' + (e.message || ''));
|
|
5483
6247
|
if (e.name === 'AbortError') {
|
|
5484
6248
|
this._updateMsg(msgId, '(请求超时或已取消)');
|
|
5485
6249
|
} else {
|
|
5486
6250
|
console.error('[AIChatDialog] 流式失败:', e);
|
|
5487
6251
|
this._updateMsg(msgId, '网络错误: ' + (e.message || '请检查连接'));
|
|
5488
6252
|
}
|
|
6253
|
+
this._finalizeMsg(msgId, this._messages.find(m => m.id === msgId)?.content || '(无回复)');
|
|
5489
6254
|
}
|
|
5490
6255
|
}
|
|
5491
6256
|
_getStreamTextEl() {
|
|
@@ -5570,7 +6335,7 @@ class AIChatDialog extends HTMLElement {
|
|
|
5570
6335
|
this._messages[idx].content = content;
|
|
5571
6336
|
delete this._messages[idx]._isStreaming;
|
|
5572
6337
|
this._messages[idx].time = this.formatTime();
|
|
5573
|
-
this._messages[idx]._status =
|
|
6338
|
+
this._messages[idx]._status = this._isErrorContent(content) ? 'error' : 'completed';
|
|
5574
6339
|
if (this._streamTypeRaf) {
|
|
5575
6340
|
cancelAnimationFrame(this._streamTypeRaf);
|
|
5576
6341
|
this._streamTypeRaf = null;
|
|
@@ -5602,6 +6367,34 @@ class AIChatDialog extends HTMLElement {
|
|
|
5602
6367
|
return false;
|
|
5603
6368
|
}
|
|
5604
6369
|
|
|
6370
|
+
// 判断错误标记内容(替换脆弱的前缀检查 startsWith('('))
|
|
6371
|
+
_ERROR_CONTENT_PATTERNS = ['(请求超时', '(等待AI处理', '(无回复)', '(已停止)', '(AI 处理超时', '错误:', '网络错误:', '抱歉,'];
|
|
6372
|
+
_isErrorContent(content) {
|
|
6373
|
+
if (!content) return true;
|
|
6374
|
+
return this._ERROR_CONTENT_PATTERNS.some(p => content.startsWith(p));
|
|
6375
|
+
}
|
|
6376
|
+
|
|
6377
|
+
// P3: 将上下文对象格式化为可读文本(拼入 prompt 前缀)
|
|
6378
|
+
_formatContextText(context) {
|
|
6379
|
+
if (!context || typeof context !== 'object') return '';
|
|
6380
|
+
const lines = ['[页面上下文]'];
|
|
6381
|
+
for (const key in context) {
|
|
6382
|
+
if (!Object.prototype.hasOwnProperty.call(context, key)) continue;
|
|
6383
|
+
const val = context[key];
|
|
6384
|
+
if (Array.isArray(val) && val.length > 0 && typeof val[0] === 'object') {
|
|
6385
|
+
lines.push(key + ':');
|
|
6386
|
+
for (const item of val) {
|
|
6387
|
+
lines.push(' - ' + Object.values(item).join(' | '));
|
|
6388
|
+
}
|
|
6389
|
+
} else if (typeof val === 'object' && val !== null) {
|
|
6390
|
+
lines.push(key + ': ' + JSON.stringify(val));
|
|
6391
|
+
} else {
|
|
6392
|
+
lines.push(key + ': ' + val);
|
|
6393
|
+
}
|
|
6394
|
+
}
|
|
6395
|
+
return lines.join('\n');
|
|
6396
|
+
}
|
|
6397
|
+
|
|
5605
6398
|
// 运行时事件管理 – incremental DOM, no renderMessages
|
|
5606
6399
|
_addRuntimeEvent(msgId, event) {
|
|
5607
6400
|
const idx = this._messages.findIndex(m => m.id === msgId);
|
|
@@ -5610,8 +6403,6 @@ class AIChatDialog extends HTMLElement {
|
|
|
5610
6403
|
const last = this._messages[idx]._runtimeEvents[this._messages[idx]._runtimeEvents.length - 1];
|
|
5611
6404
|
if (last && last._text === event._text) return;
|
|
5612
6405
|
this._messages[idx]._runtimeEvents.push(event);
|
|
5613
|
-
!['NODE_COMPLETE', 'TOOL_END', 'TOOL_RESULT'].includes(event._type);
|
|
5614
|
-
|
|
5615
6406
|
// Path 1: panel DOM exists and is alive – incremental append
|
|
5616
6407
|
if (this._runtimeEventsContainerEl && this._body.contains(this._runtimeEventsContainerEl)) {
|
|
5617
6408
|
const row = document.createElement('div');
|
|
@@ -5698,6 +6489,30 @@ class AIChatDialog extends HTMLElement {
|
|
|
5698
6489
|
panel.appendChild(eventsContainer);
|
|
5699
6490
|
return panel;
|
|
5700
6491
|
}
|
|
6492
|
+
|
|
6493
|
+
// P4: 获取自定义操作按钮列表(缓存结果避免重复调用 onMessageActions)
|
|
6494
|
+
_getCustomActions(msg, idx) {
|
|
6495
|
+
const key = '_customActions_' + idx;
|
|
6496
|
+
if (!msg[key] && typeof this._config?.onMessageActions === 'function') {
|
|
6497
|
+
try {
|
|
6498
|
+
msg[key] = this._config.onMessageActions(msg, idx) || [];
|
|
6499
|
+
} catch (e) {
|
|
6500
|
+
console.warn('[AIChatDialog] onMessageActions 执行失败:', e);
|
|
6501
|
+
msg[key] = [];
|
|
6502
|
+
}
|
|
6503
|
+
}
|
|
6504
|
+
return msg[key] || [];
|
|
6505
|
+
}
|
|
6506
|
+
|
|
6507
|
+
// P4: 生成自定义操作按钮 HTML
|
|
6508
|
+
_buildCustomActions(msg, idx) {
|
|
6509
|
+
const actions = this._getCustomActions(msg, idx);
|
|
6510
|
+
if (!actions.length) return '';
|
|
6511
|
+
return actions.map((a, i) => {
|
|
6512
|
+
const cls = a.className || '';
|
|
6513
|
+
return '<span class="action-icon custom-action-btn' + (cls ? ' ' + this.escapeAttr(cls) : '') + '" data-idx="' + idx + '" data-action="' + i + '" title="' + this.escapeAttr(a.label) + '">' + this.escapeHtml(a.label) + '</span>';
|
|
6514
|
+
}).join('');
|
|
6515
|
+
}
|
|
5701
6516
|
_buildRuntimePanel(msg, msgIdx) {
|
|
5702
6517
|
const events = msg._runtimeEvents || [];
|
|
5703
6518
|
if (events.length === 0) return '';
|
|
@@ -5734,7 +6549,7 @@ class AIChatDialog extends HTMLElement {
|
|
|
5734
6549
|
// ==================== 重新生成(与Vue regenerate 一致) ====================
|
|
5735
6550
|
|
|
5736
6551
|
async regenerate(index) {
|
|
5737
|
-
if (this._isLoading) return;
|
|
6552
|
+
if (this._isLoading || this._streaming) return;
|
|
5738
6553
|
const aiMessage = this._messages[index];
|
|
5739
6554
|
if (!aiMessage || aiMessage.type !== 'ai') return;
|
|
5740
6555
|
let userQuestion = '';
|
|
@@ -5922,6 +6737,20 @@ class AIChatDialog extends HTMLElement {
|
|
|
5922
6737
|
const n = new Date();
|
|
5923
6738
|
return `${String(n.getHours()).padStart(2, '0')}:${String(n.getMinutes()).padStart(2, '0')}`;
|
|
5924
6739
|
}
|
|
6740
|
+
|
|
6741
|
+
/**
|
|
6742
|
+
* 调试日志(仅在 config.debug === true 时输出)
|
|
6743
|
+
*/
|
|
6744
|
+
_debugLog(tag, ...args) {
|
|
6745
|
+
if (this._config?.debug) {
|
|
6746
|
+
console.log('%c[AI-SDK]%c ' + tag, 'color:#2563eb;font-weight:600', 'color:inherit', ...args);
|
|
6747
|
+
}
|
|
6748
|
+
}
|
|
6749
|
+
_debugWarn(tag, ...args) {
|
|
6750
|
+
if (this._config?.debug) {
|
|
6751
|
+
console.warn('%c[AI-SDK]%c ' + tag, 'color:#f59e0b;font-weight:600', 'color:inherit', ...args);
|
|
6752
|
+
}
|
|
6753
|
+
}
|
|
5925
6754
|
escapeHtml(s) {
|
|
5926
6755
|
if (!s) return '';
|
|
5927
6756
|
const d = document.createElement('div');
|
|
@@ -6012,7 +6841,7 @@ if (typeof window !== 'undefined') {
|
|
|
6012
6841
|
* 支持任意前端框架:Vue, React, Angular, 原生HTML等
|
|
6013
6842
|
*
|
|
6014
6843
|
* @author IBC AI Team
|
|
6015
|
-
* @version 2.0.
|
|
6844
|
+
* @version 2.0.5
|
|
6016
6845
|
*/
|
|
6017
6846
|
|
|
6018
6847
|
|
|
@@ -6024,16 +6853,53 @@ function createAIChatDialog(options = {}) {
|
|
|
6024
6853
|
// 设置属性
|
|
6025
6854
|
if (options.title) dialog.setAttribute('title', options.title);
|
|
6026
6855
|
if (options.placeholder) dialog.setAttribute('placeholder', options.placeholder);
|
|
6027
|
-
|
|
6028
|
-
if (options.
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6856
|
+
// 对话框尺寸和位置(浮窗模式可用)
|
|
6857
|
+
if (options.width) dialog.style.setProperty('--ai-dialog-width', typeof options.width === 'number' ? `${options.width}px` : options.width);
|
|
6858
|
+
if (options.height) dialog.style.setProperty('--ai-dialog-height', typeof options.height === 'number' ? `${options.height}px` : options.height);
|
|
6859
|
+
if (options.top != null) dialog.style.setProperty('--ai-dialog-top', typeof options.top === 'number' ? `${options.top}px` : options.top);
|
|
6860
|
+
if (options.right != null) dialog.style.setProperty('--ai-dialog-right', typeof options.right === 'number' ? `${options.right}px` : options.right);
|
|
6861
|
+
|
|
6862
|
+
// 挂载到指定容器或 body
|
|
6863
|
+
if (options.target) {
|
|
6864
|
+
const container = typeof options.target === 'string' ? document.querySelector(options.target) : options.target;
|
|
6865
|
+
if (container) {
|
|
6866
|
+
dialog.setAttribute('mode', 'inline');
|
|
6867
|
+
container.appendChild(dialog);
|
|
6868
|
+
} else {
|
|
6869
|
+
console.warn('[AI Web SDK] target 容器未找到,回退到 body');
|
|
6870
|
+
document.body.appendChild(dialog);
|
|
6871
|
+
}
|
|
6872
|
+
} else {
|
|
6873
|
+
document.body.appendChild(dialog);
|
|
6874
|
+
}
|
|
6032
6875
|
|
|
6033
6876
|
// 初始化配置
|
|
6034
6877
|
if (Object.keys(options).length > 0) {
|
|
6035
6878
|
dialog.init(options);
|
|
6036
6879
|
}
|
|
6880
|
+
|
|
6881
|
+
// 行内模式:挂载到 DOM 后直接展开
|
|
6882
|
+
if (options.target) {
|
|
6883
|
+
requestAnimationFrame(() => {
|
|
6884
|
+
dialog.style.position = 'relative';
|
|
6885
|
+
dialog.style.height = '100%';
|
|
6886
|
+
if (dialog.shadowRoot) {
|
|
6887
|
+
const container = dialog.shadowRoot.querySelector('.ai-float-container');
|
|
6888
|
+
const dialogEl = dialog.shadowRoot.querySelector('.ai-chat-dialog');
|
|
6889
|
+
const btn = dialog.shadowRoot.querySelector('.float-button');
|
|
6890
|
+
if (container) container.style.height = '100%';
|
|
6891
|
+
if (btn) btn.style.display = 'none';
|
|
6892
|
+
if (dialogEl) {
|
|
6893
|
+
dialogEl.style.position = 'relative';
|
|
6894
|
+
dialogEl.style.top = 'auto';
|
|
6895
|
+
dialogEl.style.right = 'auto';
|
|
6896
|
+
dialogEl.style.width = '100%';
|
|
6897
|
+
dialogEl.style.height = '100%';
|
|
6898
|
+
dialogEl.classList.add('dialog-visible');
|
|
6899
|
+
}
|
|
6900
|
+
}
|
|
6901
|
+
});
|
|
6902
|
+
}
|
|
6037
6903
|
return dialog;
|
|
6038
6904
|
}
|
|
6039
6905
|
|
|
@@ -6192,12 +7058,10 @@ function useAIChat(options = {}) {
|
|
|
6192
7058
|
},
|
|
6193
7059
|
sendMessage: content => {
|
|
6194
7060
|
if (dialogRef.current) {
|
|
6195
|
-
const input = dialogRef.current.shadowRoot?.querySelector('.
|
|
7061
|
+
const input = dialogRef.current.shadowRoot?.querySelector('.message-input');
|
|
6196
7062
|
if (input) {
|
|
6197
|
-
input.value = content;
|
|
6198
|
-
input.dispatchEvent(new Event('input'));
|
|
7063
|
+
dialogRef.current.send?.(content) || (input.value = content, input.dispatchEvent(new Event('input')), dialogRef.current.shadowRoot?.querySelector('.send-btn')?.click());
|
|
6199
7064
|
}
|
|
6200
|
-
dialogRef.current.handleSend?.() || dialogRef.current.shadowRoot?.querySelector('.ai-send-btn')?.click();
|
|
6201
7065
|
}
|
|
6202
7066
|
},
|
|
6203
7067
|
clearMessages: () => {
|
|
@@ -6218,14 +7082,14 @@ var index = {
|
|
|
6218
7082
|
createAIChatDialog,
|
|
6219
7083
|
installVuePlugin,
|
|
6220
7084
|
useAIChat,
|
|
6221
|
-
version: '2.0.
|
|
7085
|
+
version: '2.0.5'
|
|
6222
7086
|
};
|
|
6223
7087
|
|
|
6224
7088
|
// 全局暴露(UMD/浏览器环境)
|
|
6225
7089
|
if (typeof window !== 'undefined') {
|
|
6226
7090
|
window.AICreateChatDialog = createAIChatDialog;
|
|
6227
7091
|
window.AIWebSDK = {
|
|
6228
|
-
version: '2.0.
|
|
7092
|
+
version: '2.0.5',
|
|
6229
7093
|
create: createAIChatDialog,
|
|
6230
7094
|
AIChatDialog,
|
|
6231
7095
|
AIChatClient,
|