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