ibc-ai-web-sdk 2.0.2 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -221,7 +221,8 @@ class AIChatClient {
221
221
  return token;
222
222
  }).catch(error => {
223
223
  if (silent) {
224
- console.warn('[AIChatClient] Silent token refresh failed (reason=' + reason + '):', error.message);
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();
@@ -629,8 +630,9 @@ class AIChatClient {
629
630
  return;
630
631
  }
631
632
  if (MESSAGE_EVENTS.has(event)) {
632
- if (!data || isRuntimePlaceholder(data) || this.isEventLike(data)) return;
633
- handlers.onMessage?.(data);
633
+ // 后端通过空 data 块表示逻辑换行,空字符串需保留传递给上层处理
634
+ if (isRuntimePlaceholder(data) || this.isEventLike(data)) return;
635
+ handlers.onMessage?.(data || '\n');
634
636
  return;
635
637
  }
636
638
  if (DONE_EVENTS.has(event)) {
@@ -2714,6 +2716,849 @@ function createDOMPurify() {
2714
2716
  }
2715
2717
  var purify = createDOMPurify();
2716
2718
 
2719
+ /**
2720
+ * 预设主题配置
2721
+ * 提供多种常用主题,用户可以直接使用或自定义
2722
+ */
2723
+
2724
+ /**
2725
+ * 默认主题(蓝色渐变)
2726
+ */
2727
+ const DEFAULT_THEME = {
2728
+ name: 'default',
2729
+ label: '默认主题',
2730
+ colors: {
2731
+ primary: '#1890ff',
2732
+ primaryLight: '#40a9ff',
2733
+ primaryDark: '#096dd9',
2734
+ secondary: '#722ed1',
2735
+ background: '#ffffff',
2736
+ backgroundGradient: '#f8fafc',
2737
+ text: '#1e293b',
2738
+ textSecondary: '#64748b',
2739
+ userBubble: 'linear-gradient(135deg, #1890ff, #40a9ff)',
2740
+ aiBubble: '#ffffff',
2741
+ headerGradient: 'linear-gradient(90deg, rgba(24, 144, 255, 0.08), rgba(114, 46, 209, 0.08))',
2742
+ border: 'rgba(24, 144, 255, 0.15)',
2743
+ shadow: 'rgba(24, 144, 255, 0.12)',
2744
+ inputBackground: '#f8fafc',
2745
+ inputBorder: '#e2e8f0',
2746
+ loading: '#64748b',
2747
+ success: '#52c41a',
2748
+ error: '#ff4d4f',
2749
+ warning: '#faad14'
2750
+ },
2751
+ borderRadius: {
2752
+ dialog: '16px',
2753
+ bubble: '12px',
2754
+ button: '50%',
2755
+ input: '28px',
2756
+ small: '6px',
2757
+ medium: '12px'
2758
+ },
2759
+ fontSize: {
2760
+ title: '15px',
2761
+ welcomeText: '17px',
2762
+ welcomeDesc: '13px',
2763
+ message: '14px',
2764
+ time: '11px',
2765
+ small: '11px'
2766
+ },
2767
+ boxShadow: {
2768
+ dialog: '0 0 30px rgba(24, 144, 255, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
2769
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
2770
+ userBubble: '0 4px 12px rgba(24, 144, 255, 0.25)',
2771
+ button: '0 4px 12px rgba(24, 144, 255, 0.35)'
2772
+ }
2773
+ };
2774
+
2775
+ /**
2776
+ * 深色主题
2777
+ */
2778
+ const DARK_THEME = {
2779
+ name: 'dark',
2780
+ label: '深色主题',
2781
+ colors: {
2782
+ primary: '#40a9ff',
2783
+ primaryLight: '#69c0ff',
2784
+ primaryDark: '#1890ff',
2785
+ secondary: '#9254de',
2786
+ background: '#0f172a',
2787
+ backgroundGradient: '#1e293b',
2788
+ text: '#f1f5f9',
2789
+ textSecondary: '#94a3b8',
2790
+ userBubble: 'linear-gradient(135deg, #1890ff, #40a9ff)',
2791
+ aiBubble: '#1e293b',
2792
+ headerGradient: 'linear-gradient(90deg, rgba(64, 169, 255, 0.15), rgba(146, 84, 222, 0.15))',
2793
+ border: 'rgba(64, 169, 255, 0.3)',
2794
+ shadow: 'rgba(0, 0, 0, 0.3)',
2795
+ inputBackground: '#1e293b',
2796
+ inputBorder: '#334155',
2797
+ loading: '#94a3b8',
2798
+ success: '#73d13d',
2799
+ error: '#ff7875',
2800
+ warning: '#ffd666'
2801
+ },
2802
+ borderRadius: {
2803
+ dialog: '16px',
2804
+ bubble: '12px',
2805
+ button: '50%',
2806
+ input: '28px',
2807
+ small: '6px',
2808
+ medium: '12px'
2809
+ },
2810
+ fontSize: {
2811
+ title: '15px',
2812
+ welcomeText: '17px',
2813
+ welcomeDesc: '13px',
2814
+ message: '14px',
2815
+ time: '11px',
2816
+ small: '11px'
2817
+ },
2818
+ boxShadow: {
2819
+ dialog: '0 0 30px rgba(64, 169, 255, 0.15), 0 8px 32px rgba(0, 0, 0, 0.4)',
2820
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.2)',
2821
+ userBubble: '0 4px 12px rgba(24, 144, 255, 0.3)',
2822
+ button: '0 4px 12px rgba(24, 144, 255, 0.4)'
2823
+ }
2824
+ };
2825
+
2826
+ /**
2827
+ * 清新主题(绿色系)
2828
+ */
2829
+ const FRESH_THEME = {
2830
+ name: 'fresh',
2831
+ label: '清新主题',
2832
+ colors: {
2833
+ primary: '#52c41a',
2834
+ primaryLight: '#73d13d',
2835
+ primaryDark: '#389e0d',
2836
+ secondary: '#1890ff',
2837
+ background: '#ffffff',
2838
+ backgroundGradient: '#f6ffed',
2839
+ text: '#1e293b',
2840
+ textSecondary: '#64748b',
2841
+ userBubble: 'linear-gradient(135deg, #52c41a, #73d13d)',
2842
+ aiBubble: '#ffffff',
2843
+ headerGradient: 'linear-gradient(90deg, rgba(82, 196, 26, 0.08), rgba(24, 144, 255, 0.08))',
2844
+ border: 'rgba(82, 196, 26, 0.15)',
2845
+ shadow: 'rgba(82, 196, 26, 0.12)',
2846
+ inputBackground: '#f6ffed',
2847
+ inputBorder: '#d9f7be',
2848
+ loading: '#64748b',
2849
+ success: '#52c41a',
2850
+ error: '#ff4d4f',
2851
+ warning: '#faad14'
2852
+ },
2853
+ borderRadius: {
2854
+ dialog: '20px',
2855
+ bubble: '16px',
2856
+ button: '50%',
2857
+ input: '32px',
2858
+ small: '8px',
2859
+ medium: '16px'
2860
+ },
2861
+ fontSize: {
2862
+ title: '15px',
2863
+ welcomeText: '17px',
2864
+ welcomeDesc: '13px',
2865
+ message: '14px',
2866
+ time: '11px',
2867
+ small: '11px'
2868
+ },
2869
+ boxShadow: {
2870
+ dialog: '0 0 30px rgba(82, 196, 26, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
2871
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
2872
+ userBubble: '0 4px 12px rgba(82, 196, 26, 0.25)',
2873
+ button: '0 4px 12px rgba(82, 196, 26, 0.35)'
2874
+ }
2875
+ };
2876
+
2877
+ /**
2878
+ * 活力主题(橙色系)
2879
+ */
2880
+ const VIBRANT_THEME = {
2881
+ name: 'vibrant',
2882
+ label: '活力主题',
2883
+ colors: {
2884
+ primary: '#fa8c16',
2885
+ primaryLight: '#ffa940',
2886
+ primaryDark: '#d46b08',
2887
+ secondary: '#f5222d',
2888
+ background: '#ffffff',
2889
+ backgroundGradient: '#fff7e6',
2890
+ text: '#1e293b',
2891
+ textSecondary: '#64748b',
2892
+ userBubble: 'linear-gradient(135deg, #fa8c16, #ffa940)',
2893
+ aiBubble: '#ffffff',
2894
+ headerGradient: 'linear-gradient(90deg, rgba(250, 140, 22, 0.08), rgba(245, 34, 45, 0.08))',
2895
+ border: 'rgba(250, 140, 22, 0.15)',
2896
+ shadow: 'rgba(250, 140, 22, 0.12)',
2897
+ inputBackground: '#fff7e6',
2898
+ inputBorder: '#ffd591',
2899
+ loading: '#64748b',
2900
+ success: '#52c41a',
2901
+ error: '#ff4d4f',
2902
+ warning: '#faad14'
2903
+ },
2904
+ borderRadius: {
2905
+ dialog: '12px',
2906
+ bubble: '10px',
2907
+ button: '50%',
2908
+ input: '24px',
2909
+ small: '4px',
2910
+ medium: '10px'
2911
+ },
2912
+ fontSize: {
2913
+ title: '15px',
2914
+ welcomeText: '17px',
2915
+ welcomeDesc: '13px',
2916
+ message: '14px',
2917
+ time: '11px',
2918
+ small: '11px'
2919
+ },
2920
+ boxShadow: {
2921
+ dialog: '0 0 30px rgba(250, 140, 22, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
2922
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
2923
+ userBubble: '0 4px 12px rgba(250, 140, 22, 0.25)',
2924
+ button: '0 4px 12px rgba(250, 140, 22, 0.35)'
2925
+ }
2926
+ };
2927
+
2928
+ /**
2929
+ * 浪漫主题(粉色系)
2930
+ */
2931
+ const ROMANTIC_THEME = {
2932
+ name: 'romantic',
2933
+ label: '浪漫主题',
2934
+ colors: {
2935
+ primary: '#eb2f96',
2936
+ primaryLight: '#fb6f92',
2937
+ primaryDark: '#c41d7f',
2938
+ secondary: '#722ed1',
2939
+ background: '#ffffff',
2940
+ backgroundGradient: '#fff0f6',
2941
+ text: '#1e293b',
2942
+ textSecondary: '#64748b',
2943
+ userBubble: 'linear-gradient(135deg, #eb2f96, #fb6f92)',
2944
+ aiBubble: '#ffffff',
2945
+ headerGradient: 'linear-gradient(90deg, rgba(235, 47, 150, 0.08), rgba(114, 46, 209, 0.08))',
2946
+ border: 'rgba(235, 47, 150, 0.15)',
2947
+ shadow: 'rgba(235, 47, 150, 0.12)',
2948
+ inputBackground: '#fff0f6',
2949
+ inputBorder: '#ffadd2',
2950
+ loading: '#64748b',
2951
+ success: '#52c41a',
2952
+ error: '#ff4d4f',
2953
+ warning: '#faad14'
2954
+ },
2955
+ borderRadius: {
2956
+ dialog: '24px',
2957
+ bubble: '16px',
2958
+ button: '50%',
2959
+ input: '32px',
2960
+ small: '8px',
2961
+ medium: '16px'
2962
+ },
2963
+ fontSize: {
2964
+ title: '15px',
2965
+ welcomeText: '17px',
2966
+ welcomeDesc: '13px',
2967
+ message: '14px',
2968
+ time: '11px',
2969
+ small: '11px'
2970
+ },
2971
+ boxShadow: {
2972
+ dialog: '0 0 30px rgba(235, 47, 150, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
2973
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
2974
+ userBubble: '0 4px 12px rgba(235, 47, 150, 0.25)',
2975
+ button: '0 4px 12px rgba(235, 47, 150, 0.35)'
2976
+ }
2977
+ };
2978
+
2979
+ /**
2980
+ * 紫色主题(优雅神秘)
2981
+ */
2982
+ const PURPLE_THEME = {
2983
+ name: 'purple',
2984
+ label: '紫色主题',
2985
+ colors: {
2986
+ primary: '#722ed1',
2987
+ primaryLight: '#9254de',
2988
+ primaryDark: '#531dab',
2989
+ secondary: '#1890ff',
2990
+ background: '#ffffff',
2991
+ backgroundGradient: '#f9f0ff',
2992
+ text: '#1e293b',
2993
+ textSecondary: '#64748b',
2994
+ userBubble: 'linear-gradient(135deg, #722ed1, #9254de)',
2995
+ aiBubble: '#ffffff',
2996
+ headerGradient: 'linear-gradient(90deg, rgba(114, 46, 209, 0.08), rgba(24, 144, 255, 0.08))',
2997
+ border: 'rgba(114, 46, 209, 0.15)',
2998
+ shadow: 'rgba(114, 46, 209, 0.12)',
2999
+ inputBackground: '#f9f0ff',
3000
+ inputBorder: '#d3adf7',
3001
+ loading: '#64748b',
3002
+ success: '#52c41a',
3003
+ error: '#ff4d4f',
3004
+ warning: '#faad14'
3005
+ },
3006
+ borderRadius: {
3007
+ dialog: '16px',
3008
+ bubble: '12px',
3009
+ button: '50%',
3010
+ input: '28px',
3011
+ small: '6px',
3012
+ medium: '12px'
3013
+ },
3014
+ fontSize: {
3015
+ title: '15px',
3016
+ welcomeText: '17px',
3017
+ welcomeDesc: '13px',
3018
+ message: '14px',
3019
+ time: '11px',
3020
+ small: '11px'
3021
+ },
3022
+ boxShadow: {
3023
+ dialog: '0 0 30px rgba(114, 46, 209, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
3024
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
3025
+ userBubble: '0 4px 12px rgba(114, 46, 209, 0.25)',
3026
+ button: '0 4px 12px rgba(114, 46, 209, 0.35)'
3027
+ }
3028
+ };
3029
+
3030
+ /**
3031
+ * 海洋主题(深蓝深海)
3032
+ */
3033
+ const OCEAN_THEME = {
3034
+ name: 'ocean',
3035
+ label: '海洋主题',
3036
+ colors: {
3037
+ primary: '#0077b6',
3038
+ primaryLight: '#00b4d8',
3039
+ primaryDark: '#023e8a',
3040
+ secondary: '#00b4d8',
3041
+ background: '#ffffff',
3042
+ backgroundGradient: '#f0f9ff',
3043
+ text: '#1e293b',
3044
+ textSecondary: '#64748b',
3045
+ userBubble: 'linear-gradient(135deg, #0077b6, #00b4d8)',
3046
+ aiBubble: '#ffffff',
3047
+ headerGradient: 'linear-gradient(90deg, rgba(0, 119, 182, 0.08), rgba(0, 180, 216, 0.08))',
3048
+ border: 'rgba(0, 119, 182, 0.15)',
3049
+ shadow: 'rgba(0, 119, 182, 0.12)',
3050
+ inputBackground: '#f0f9ff',
3051
+ inputBorder: '#bae6fd',
3052
+ loading: '#64748b',
3053
+ success: '#52c41a',
3054
+ error: '#ff4d4f',
3055
+ warning: '#faad14'
3056
+ },
3057
+ borderRadius: {
3058
+ dialog: '14px',
3059
+ bubble: '10px',
3060
+ button: '50%',
3061
+ input: '28px',
3062
+ small: '6px',
3063
+ medium: '12px'
3064
+ },
3065
+ fontSize: {
3066
+ title: '15px',
3067
+ welcomeText: '17px',
3068
+ welcomeDesc: '13px',
3069
+ message: '14px',
3070
+ time: '11px',
3071
+ small: '11px'
3072
+ },
3073
+ boxShadow: {
3074
+ dialog: '0 0 30px rgba(0, 119, 182, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
3075
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
3076
+ userBubble: '0 4px 12px rgba(0, 119, 182, 0.25)',
3077
+ button: '0 4px 12px rgba(0, 119, 182, 0.35)'
3078
+ }
3079
+ };
3080
+
3081
+ /**
3082
+ * 暮光主题(紫罗兰渐变)
3083
+ */
3084
+ const TWILIGHT_THEME = {
3085
+ name: 'twilight',
3086
+ label: '暮光主题',
3087
+ colors: {
3088
+ primary: '#9333ea',
3089
+ primaryLight: '#a855f7',
3090
+ primaryDark: '#7e22ce',
3091
+ secondary: '#ec4899',
3092
+ background: '#ffffff',
3093
+ backgroundGradient: '#faf5ff',
3094
+ text: '#1e293b',
3095
+ textSecondary: '#64748b',
3096
+ userBubble: 'linear-gradient(135deg, #9333ea, #ec4899)',
3097
+ aiBubble: '#ffffff',
3098
+ headerGradient: 'linear-gradient(90deg, rgba(147, 51, 234, 0.08), rgba(236, 72, 153, 0.08))',
3099
+ border: 'rgba(147, 51, 234, 0.15)',
3100
+ shadow: 'rgba(147, 51, 234, 0.12)',
3101
+ inputBackground: '#faf5ff',
3102
+ inputBorder: '#e9d5ff',
3103
+ loading: '#64748b',
3104
+ success: '#52c41a',
3105
+ error: '#ff4d4f',
3106
+ warning: '#faad14'
3107
+ },
3108
+ borderRadius: {
3109
+ dialog: '18px',
3110
+ bubble: '14px',
3111
+ button: '50%',
3112
+ input: '30px',
3113
+ small: '8px',
3114
+ medium: '14px'
3115
+ },
3116
+ fontSize: {
3117
+ title: '15px',
3118
+ welcomeText: '17px',
3119
+ welcomeDesc: '13px',
3120
+ message: '14px',
3121
+ time: '11px',
3122
+ small: '11px'
3123
+ },
3124
+ boxShadow: {
3125
+ dialog: '0 0 30px rgba(147, 51, 234, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
3126
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
3127
+ userBubble: '0 4px 12px rgba(147, 51, 234, 0.25)',
3128
+ button: '0 4px 12px rgba(147, 51, 234, 0.35)'
3129
+ }
3130
+ };
3131
+
3132
+ /**
3133
+ * 薄荷主题(青绿色)
3134
+ */
3135
+ const MINT_THEME = {
3136
+ name: 'mint',
3137
+ label: '薄荷主题',
3138
+ colors: {
3139
+ primary: '#14b8a6',
3140
+ primaryLight: '#2dd4bf',
3141
+ primaryDark: '#0d9488',
3142
+ secondary: '#06b6d4',
3143
+ background: '#ffffff',
3144
+ backgroundGradient: '#f0fdfa',
3145
+ text: '#1e293b',
3146
+ textSecondary: '#64748b',
3147
+ userBubble: 'linear-gradient(135deg, #14b8a6, #2dd4bf)',
3148
+ aiBubble: '#ffffff',
3149
+ headerGradient: 'linear-gradient(90deg, rgba(20, 184, 166, 0.08), rgba(6, 182, 212, 0.08))',
3150
+ border: 'rgba(20, 184, 166, 0.15)',
3151
+ shadow: 'rgba(20, 184, 166, 0.12)',
3152
+ inputBackground: '#f0fdfa',
3153
+ inputBorder: '#99f6e4',
3154
+ loading: '#64748b',
3155
+ success: '#52c41a',
3156
+ error: '#ff4d4f',
3157
+ warning: '#faad14'
3158
+ },
3159
+ borderRadius: {
3160
+ dialog: '16px',
3161
+ bubble: '12px',
3162
+ button: '50%',
3163
+ input: '28px',
3164
+ small: '6px',
3165
+ medium: '12px'
3166
+ },
3167
+ fontSize: {
3168
+ title: '15px',
3169
+ welcomeText: '17px',
3170
+ welcomeDesc: '13px',
3171
+ message: '14px',
3172
+ time: '11px',
3173
+ small: '11px'
3174
+ },
3175
+ boxShadow: {
3176
+ dialog: '0 0 30px rgba(20, 184, 166, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
3177
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
3178
+ userBubble: '0 4px 12px rgba(20, 184, 166, 0.25)',
3179
+ button: '0 4px 12px rgba(20, 184, 166, 0.35)'
3180
+ }
3181
+ };
3182
+
3183
+ /**
3184
+ * 玫瑰主题(深红色)
3185
+ */
3186
+ const ROSE_THEME = {
3187
+ name: 'rose',
3188
+ label: '玫瑰主题',
3189
+ colors: {
3190
+ primary: '#e11d48',
3191
+ primaryLight: '#fb7185',
3192
+ primaryDark: '#be123c',
3193
+ secondary: '#f43f5e',
3194
+ background: '#ffffff',
3195
+ backgroundGradient: '#fff1f2',
3196
+ text: '#1e293b',
3197
+ textSecondary: '#64748b',
3198
+ userBubble: 'linear-gradient(135deg, #e11d48, #fb7185)',
3199
+ aiBubble: '#ffffff',
3200
+ headerGradient: 'linear-gradient(90deg, rgba(225, 29, 72, 0.08), rgba(244, 63, 94, 0.08))',
3201
+ border: 'rgba(225, 29, 72, 0.15)',
3202
+ shadow: 'rgba(225, 29, 72, 0.12)',
3203
+ inputBackground: '#fff1f2',
3204
+ inputBorder: '#fecdd3',
3205
+ loading: '#64748b',
3206
+ success: '#52c41a',
3207
+ error: '#ff4d4f',
3208
+ warning: '#faad14'
3209
+ },
3210
+ borderRadius: {
3211
+ dialog: '16px',
3212
+ bubble: '12px',
3213
+ button: '50%',
3214
+ input: '28px',
3215
+ small: '6px',
3216
+ medium: '12px'
3217
+ },
3218
+ fontSize: {
3219
+ title: '15px',
3220
+ welcomeText: '17px',
3221
+ welcomeDesc: '13px',
3222
+ message: '14px',
3223
+ time: '11px',
3224
+ small: '11px'
3225
+ },
3226
+ boxShadow: {
3227
+ dialog: '0 0 30px rgba(225, 29, 72, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
3228
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
3229
+ userBubble: '0 4px 12px rgba(225, 29, 72, 0.25)',
3230
+ button: '0 4px 12px rgba(225, 29, 72, 0.35)'
3231
+ }
3232
+ };
3233
+
3234
+ /**
3235
+ * 极光主题(蓝绿渐变)
3236
+ */
3237
+ const AURORA_THEME = {
3238
+ name: 'aurora',
3239
+ label: '极光主题',
3240
+ colors: {
3241
+ primary: '#0ea5e9',
3242
+ primaryLight: '#38bdf8',
3243
+ primaryDark: '#0284c7',
3244
+ secondary: '#10b981',
3245
+ background: '#ffffff',
3246
+ backgroundGradient: '#f0f9ff',
3247
+ text: '#1e293b',
3248
+ textSecondary: '#64748b',
3249
+ userBubble: 'linear-gradient(135deg, #0ea5e9, #10b981)',
3250
+ aiBubble: '#ffffff',
3251
+ headerGradient: 'linear-gradient(90deg, rgba(14, 165, 233, 0.08), rgba(16, 185, 129, 0.08))',
3252
+ border: 'rgba(14, 165, 233, 0.15)',
3253
+ shadow: 'rgba(14, 165, 233, 0.12)',
3254
+ inputBackground: '#f0f9ff',
3255
+ inputBorder: '#bae6fd',
3256
+ loading: '#64748b',
3257
+ success: '#52c41a',
3258
+ error: '#ff4d4f',
3259
+ warning: '#faad14'
3260
+ },
3261
+ borderRadius: {
3262
+ dialog: '20px',
3263
+ bubble: '14px',
3264
+ button: '50%',
3265
+ input: '30px',
3266
+ small: '8px',
3267
+ medium: '14px'
3268
+ },
3269
+ fontSize: {
3270
+ title: '15px',
3271
+ welcomeText: '17px',
3272
+ welcomeDesc: '13px',
3273
+ message: '14px',
3274
+ time: '11px',
3275
+ small: '11px'
3276
+ },
3277
+ boxShadow: {
3278
+ dialog: '0 0 30px rgba(14, 165, 233, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
3279
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
3280
+ userBubble: '0 4px 12px rgba(14, 165, 233, 0.25)',
3281
+ button: '0 4px 12px rgba(14, 165, 233, 0.35)'
3282
+ }
3283
+ };
3284
+
3285
+ /**
3286
+ * 薰衣草主题(淡紫色)
3287
+ */
3288
+ const LAVENDER_THEME = {
3289
+ name: 'lavender',
3290
+ label: '薰衣草主题',
3291
+ colors: {
3292
+ primary: '#8b5cf6',
3293
+ primaryLight: '#a78bfa',
3294
+ primaryDark: '#7c3aed',
3295
+ secondary: '#c084fc',
3296
+ background: '#ffffff',
3297
+ backgroundGradient: '#faf5ff',
3298
+ text: '#1e293b',
3299
+ textSecondary: '#64748b',
3300
+ userBubble: 'linear-gradient(135deg, #8b5cf6, #c084fc)',
3301
+ aiBubble: '#ffffff',
3302
+ headerGradient: 'linear-gradient(90deg, rgba(139, 92, 246, 0.08), rgba(192, 132, 252, 0.08))',
3303
+ border: 'rgba(139, 92, 246, 0.15)',
3304
+ shadow: 'rgba(139, 92, 246, 0.12)',
3305
+ inputBackground: '#faf5ff',
3306
+ inputBorder: '#ddd6fe',
3307
+ loading: '#64748b',
3308
+ success: '#52c41a',
3309
+ error: '#ff4d4f',
3310
+ warning: '#faad14'
3311
+ },
3312
+ borderRadius: {
3313
+ dialog: '22px',
3314
+ bubble: '16px',
3315
+ button: '50%',
3316
+ input: '32px',
3317
+ small: '8px',
3318
+ medium: '16px'
3319
+ },
3320
+ fontSize: {
3321
+ title: '15px',
3322
+ welcomeText: '17px',
3323
+ welcomeDesc: '13px',
3324
+ message: '14px',
3325
+ time: '11px',
3326
+ small: '11px'
3327
+ },
3328
+ boxShadow: {
3329
+ dialog: '0 0 30px rgba(139, 92, 246, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
3330
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
3331
+ userBubble: '0 4px 12px rgba(139, 92, 246, 0.25)',
3332
+ button: '0 4px 12px rgba(139, 92, 246, 0.35)'
3333
+ }
3334
+ };
3335
+
3336
+ /**
3337
+ * 珊瑚主题(粉橙色)
3338
+ */
3339
+ const CORAL_THEME = {
3340
+ name: 'coral',
3341
+ label: '珊瑚主题',
3342
+ colors: {
3343
+ primary: '#f97316',
3344
+ primaryLight: '#fb923c',
3345
+ primaryDark: '#ea580c',
3346
+ secondary: '#f43f5e',
3347
+ background: '#ffffff',
3348
+ backgroundGradient: '#fff7ed',
3349
+ text: '#1e293b',
3350
+ textSecondary: '#64748b',
3351
+ userBubble: 'linear-gradient(135deg, #f97316, #fb923c)',
3352
+ aiBubble: '#ffffff',
3353
+ headerGradient: 'linear-gradient(90deg, rgba(249, 115, 22, 0.08), rgba(244, 63, 94, 0.08))',
3354
+ border: 'rgba(249, 115, 22, 0.15)',
3355
+ shadow: 'rgba(249, 115, 22, 0.12)',
3356
+ inputBackground: '#fff7ed',
3357
+ inputBorder: '#fed7aa',
3358
+ loading: '#64748b',
3359
+ success: '#52c41a',
3360
+ error: '#ff4d4f',
3361
+ warning: '#faad14'
3362
+ },
3363
+ borderRadius: {
3364
+ dialog: '14px',
3365
+ bubble: '10px',
3366
+ button: '50%',
3367
+ input: '26px',
3368
+ small: '6px',
3369
+ medium: '10px'
3370
+ },
3371
+ fontSize: {
3372
+ title: '15px',
3373
+ welcomeText: '17px',
3374
+ welcomeDesc: '13px',
3375
+ message: '14px',
3376
+ time: '11px',
3377
+ small: '11px'
3378
+ },
3379
+ boxShadow: {
3380
+ dialog: '0 0 30px rgba(249, 115, 22, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
3381
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
3382
+ userBubble: '0 4px 12px rgba(249, 115, 22, 0.25)',
3383
+ button: '0 4px 12px rgba(249, 115, 22, 0.35)'
3384
+ }
3385
+ };
3386
+
3387
+ /**
3388
+ * 翡翠主题(深绿色)
3389
+ */
3390
+ const JADE_THEME = {
3391
+ name: 'jade',
3392
+ label: '翡翠主题',
3393
+ colors: {
3394
+ primary: '#059669',
3395
+ primaryLight: '#10b981',
3396
+ primaryDark: '#047857',
3397
+ secondary: '#34d399',
3398
+ background: '#ffffff',
3399
+ backgroundGradient: '#f0fdf4',
3400
+ text: '#1e293b',
3401
+ textSecondary: '#64748b',
3402
+ userBubble: 'linear-gradient(135deg, #059669, #10b981)',
3403
+ aiBubble: '#ffffff',
3404
+ headerGradient: 'linear-gradient(90deg, rgba(5, 150, 105, 0.08), rgba(52, 211, 153, 0.08))',
3405
+ border: 'rgba(5, 150, 105, 0.15)',
3406
+ shadow: 'rgba(5, 150, 105, 0.12)',
3407
+ inputBackground: '#f0fdf4',
3408
+ inputBorder: '#bbf7d0',
3409
+ loading: '#64748b',
3410
+ success: '#52c41a',
3411
+ error: '#ff4d4f',
3412
+ warning: '#faad14'
3413
+ },
3414
+ borderRadius: {
3415
+ dialog: '16px',
3416
+ bubble: '12px',
3417
+ button: '50%',
3418
+ input: '28px',
3419
+ small: '6px',
3420
+ medium: '12px'
3421
+ },
3422
+ fontSize: {
3423
+ title: '15px',
3424
+ welcomeText: '17px',
3425
+ welcomeDesc: '13px',
3426
+ message: '14px',
3427
+ time: '11px',
3428
+ small: '11px'
3429
+ },
3430
+ boxShadow: {
3431
+ dialog: '0 0 30px rgba(5, 150, 105, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
3432
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
3433
+ userBubble: '0 4px 12px rgba(5, 150, 105, 0.25)',
3434
+ button: '0 4px 12px rgba(5, 150, 105, 0.35)'
3435
+ }
3436
+ };
3437
+
3438
+ /**
3439
+ * 星空主题(深蓝紫色)
3440
+ */
3441
+ const STARSKY_THEME = {
3442
+ name: 'starsky',
3443
+ label: '星空主题',
3444
+ colors: {
3445
+ primary: '#6366f1',
3446
+ primaryLight: '#818cf8',
3447
+ primaryDark: '#4f46e5',
3448
+ secondary: '#a855f7',
3449
+ background: '#0f172a',
3450
+ backgroundGradient: '#1e1b4b',
3451
+ text: '#e2e8f0',
3452
+ textSecondary: '#94a3b8',
3453
+ userBubble: 'linear-gradient(135deg, #6366f1, #a855f7)',
3454
+ aiBubble: '#1e1b4b',
3455
+ headerGradient: 'linear-gradient(90deg, rgba(99, 102, 241, 0.15), rgba(168, 85, 247, 0.15))',
3456
+ border: 'rgba(99, 102, 241, 0.3)',
3457
+ shadow: 'rgba(0, 0, 0, 0.3)',
3458
+ inputBackground: '#1e1b4b',
3459
+ inputBorder: '#312e81',
3460
+ loading: '#94a3b8',
3461
+ success: '#34d399',
3462
+ error: '#f87171',
3463
+ warning: '#fbbf24'
3464
+ },
3465
+ borderRadius: {
3466
+ dialog: '18px',
3467
+ bubble: '14px',
3468
+ button: '50%',
3469
+ input: '30px',
3470
+ small: '8px',
3471
+ medium: '14px'
3472
+ },
3473
+ fontSize: {
3474
+ title: '15px',
3475
+ welcomeText: '17px',
3476
+ welcomeDesc: '13px',
3477
+ message: '14px',
3478
+ time: '11px',
3479
+ small: '11px'
3480
+ },
3481
+ boxShadow: {
3482
+ dialog: '0 0 30px rgba(99, 102, 241, 0.2), 0 8px 32px rgba(0, 0, 0, 0.4)',
3483
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.2)',
3484
+ userBubble: '0 4px 12px rgba(99, 102, 241, 0.3)',
3485
+ button: '0 4px 12px rgba(99, 102, 241, 0.4)'
3486
+ }
3487
+ };
3488
+
3489
+ /**
3490
+ * 日落主题(暖色调)
3491
+ */
3492
+ const SUNSET_THEME = {
3493
+ name: 'sunset',
3494
+ label: '日落主题',
3495
+ colors: {
3496
+ primary: '#ea580c',
3497
+ primaryLight: '#f97316',
3498
+ primaryDark: '#c2410c',
3499
+ secondary: '#dc2626',
3500
+ background: '#ffffff',
3501
+ backgroundGradient: '#fff8f0',
3502
+ text: '#1e293b',
3503
+ textSecondary: '#64748b',
3504
+ userBubble: 'linear-gradient(135deg, #ea580c, #dc2626)',
3505
+ aiBubble: '#ffffff',
3506
+ headerGradient: 'linear-gradient(90deg, rgba(234, 88, 12, 0.08), rgba(220, 38, 38, 0.08))',
3507
+ border: 'rgba(234, 88, 12, 0.15)',
3508
+ shadow: 'rgba(234, 88, 12, 0.12)',
3509
+ inputBackground: '#fff8f0',
3510
+ inputBorder: '#fed7aa',
3511
+ loading: '#64748b',
3512
+ success: '#52c41a',
3513
+ error: '#ff4d4f',
3514
+ warning: '#faad14'
3515
+ },
3516
+ borderRadius: {
3517
+ dialog: '16px',
3518
+ bubble: '12px',
3519
+ button: '50%',
3520
+ input: '28px',
3521
+ small: '6px',
3522
+ medium: '12px'
3523
+ },
3524
+ fontSize: {
3525
+ title: '15px',
3526
+ welcomeText: '17px',
3527
+ welcomeDesc: '13px',
3528
+ message: '14px',
3529
+ time: '11px',
3530
+ small: '11px'
3531
+ },
3532
+ boxShadow: {
3533
+ dialog: '0 0 30px rgba(234, 88, 12, 0.12), 0 8px 32px rgba(0, 0, 0, 0.1)',
3534
+ bubble: '0 2px 8px rgba(0, 0, 0, 0.06)',
3535
+ userBubble: '0 4px 12px rgba(234, 88, 12, 0.25)',
3536
+ button: '0 4px 12px rgba(234, 88, 12, 0.35)'
3537
+ }
3538
+ };
3539
+
3540
+ /**
3541
+ * 所有预设主题列表
3542
+ */
3543
+ const PRESET_THEMES = {
3544
+ DEFAULT: DEFAULT_THEME,
3545
+ DARK: DARK_THEME,
3546
+ FRESH: FRESH_THEME,
3547
+ VIBRANT: VIBRANT_THEME,
3548
+ ROMANTIC: ROMANTIC_THEME,
3549
+ PURPLE: PURPLE_THEME,
3550
+ OCEAN: OCEAN_THEME,
3551
+ TWILIGHT: TWILIGHT_THEME,
3552
+ MINT: MINT_THEME,
3553
+ ROSE: ROSE_THEME,
3554
+ AURORA: AURORA_THEME,
3555
+ LAVENDER: LAVENDER_THEME,
3556
+ CORAL: CORAL_THEME,
3557
+ JADE: JADE_THEME,
3558
+ STARSKY: STARSKY_THEME,
3559
+ SUNSET: SUNSET_THEME
3560
+ };
3561
+
2717
3562
  /**
2718
3563
  * AIChatDialog - 纯JavaScript实现的AI对话组件 (Web Components)
2719
3564
  * 样式与功能完全对齐 Vue 版本(1:1 复刻)
@@ -2768,312 +3613,6 @@ const THEME_COLOR_KEY_MAP = {
2768
3613
  };
2769
3614
 
2770
3615
  // ========== 16种预设主题(与Vue版themes.js完全一致) ==========
2771
- const PRESET_THEMES = {
2772
- DEFAULT: {
2773
- colors: {
2774
- primary: '#1890ff',
2775
- primaryLight: '#40a9ff',
2776
- primaryDark: '#096dd9',
2777
- secondary: '#722ed1',
2778
- background: '#ffffff',
2779
- backgroundGradient: '#f8fafc',
2780
- text: '#1e293b',
2781
- textSecondary: '#64748b',
2782
- userBubble: 'linear-gradient(135deg, #1890ff, #40a9ff)',
2783
- aiBubble: '#ffffff',
2784
- headerGradient: 'linear-gradient(90deg, rgba(24,144,255,0.08), rgba(114,46,209,0.08))',
2785
- border: 'rgba(24,144,255,0.15)',
2786
- shadow: 'rgba(24,144,255,0.12)',
2787
- inputBackground: '#f8fafc',
2788
- inputBorder: '#e2e8f0'
2789
- }
2790
- },
2791
- DARK: {
2792
- colors: {
2793
- primary: '#40a9ff',
2794
- primaryLight: '#69c0ff',
2795
- primaryDark: '#1890ff',
2796
- secondary: '#9254de',
2797
- background: '#0f172a',
2798
- backgroundGradient: '#1e293b',
2799
- text: '#f1f5f9',
2800
- textSecondary: '#94a3b8',
2801
- userBubble: 'linear-gradient(135deg, #1890ff, #40a9ff)',
2802
- aiBubble: '#1e293b',
2803
- headerGradient: 'linear-gradient(90deg, rgba(64,169,255,0.15), rgba(146,84,222,0.15))',
2804
- border: 'rgba(64,169,255,0.3)',
2805
- shadow: 'rgba(0,0,0,0.3)',
2806
- inputBackground: '#1e293b',
2807
- inputBorder: '#334155'
2808
- }
2809
- },
2810
- FRESH: {
2811
- colors: {
2812
- primary: '#52c41a',
2813
- primaryLight: '#73d13d',
2814
- primaryDark: '#389e0d',
2815
- secondary: '#1890ff',
2816
- background: '#ffffff',
2817
- backgroundGradient: '#f6ffed',
2818
- text: '#1e293b',
2819
- textSecondary: '#64748b',
2820
- userBubble: 'linear-gradient(135deg, #52c41a, #73d13d)',
2821
- aiBubble: '#ffffff',
2822
- headerGradient: 'linear-gradient(90deg, rgba(82,196,26,0.08), rgba(24,144,255,0.08))',
2823
- border: 'rgba(82,196,26,0.15)',
2824
- shadow: 'rgba(82,196,26,0.12)',
2825
- inputBackground: '#f6ffed',
2826
- inputBorder: '#d9f7be'
2827
- }
2828
- },
2829
- VIBRANT: {
2830
- colors: {
2831
- primary: '#fa8c16',
2832
- primaryLight: '#ffa940',
2833
- primaryDark: '#d46b08',
2834
- secondary: '#f5222d',
2835
- background: '#ffffff',
2836
- backgroundGradient: '#fff7e6',
2837
- text: '#1e293b',
2838
- textSecondary: '#64748b',
2839
- userBubble: 'linear-gradient(135deg, #fa8c16, #ffa940)',
2840
- aiBubble: '#ffffff',
2841
- headerGradient: 'linear-gradient(90deg, rgba(250,140,22,0.08), rgba(245,34,45,0.08))',
2842
- border: 'rgba(250,140,22,0.15)',
2843
- shadow: 'rgba(250,140,22,0.12)',
2844
- inputBackground: '#fff7e6',
2845
- inputBorder: '#ffd591'
2846
- }
2847
- },
2848
- ROMANTIC: {
2849
- colors: {
2850
- primary: '#eb2f96',
2851
- primaryLight: '#fb6f92',
2852
- primaryDark: '#c41d7f',
2853
- secondary: '#722ed1',
2854
- background: '#ffffff',
2855
- backgroundGradient: '#fff0f6',
2856
- text: '#1e293b',
2857
- textSecondary: '#64748b',
2858
- userBubble: 'linear-gradient(135deg, #eb2f96, #fb6f92)',
2859
- aiBubble: '#ffffff',
2860
- headerGradient: 'linear-gradient(90deg, rgba(235,47,150,0.08), rgba(114,46,209,0.08))',
2861
- border: 'rgba(235,47,150,0.15)',
2862
- shadow: 'rgba(235,47,150,0.12)',
2863
- inputBackground: '#fff0f6',
2864
- inputBorder: '#ffadd2'
2865
- }
2866
- },
2867
- PURPLE: {
2868
- colors: {
2869
- primary: '#722ed1',
2870
- primaryLight: '#9254de',
2871
- primaryDark: '#531dab',
2872
- secondary: '#1890ff',
2873
- background: '#ffffff',
2874
- backgroundGradient: '#f9f0ff',
2875
- text: '#1e293b',
2876
- textSecondary: '#64748b',
2877
- userBubble: 'linear-gradient(135deg, #722ed1, #9254de)',
2878
- aiBubble: '#ffffff',
2879
- headerGradient: 'linear-gradient(90deg, rgba(114,46,209,0.08), rgba(24,144,255,0.08))',
2880
- border: 'rgba(114,46,209,0.15)',
2881
- shadow: 'rgba(114,46,209,0.12)',
2882
- inputBackground: '#f9f0ff',
2883
- inputBorder: '#d3adf7'
2884
- }
2885
- },
2886
- OCEAN: {
2887
- colors: {
2888
- primary: '#0077b6',
2889
- primaryLight: '#00b4d8',
2890
- primaryDark: '#023e8a',
2891
- secondary: '#00b4d8',
2892
- background: '#ffffff',
2893
- backgroundGradient: '#f0f9ff',
2894
- text: '#1e293b',
2895
- textSecondary: '#64748b',
2896
- userBubble: 'linear-gradient(135deg, #0077b6, #00b4d8)',
2897
- aiBubble: '#ffffff',
2898
- headerGradient: 'linear-gradient(90deg, rgba(0,119,182,0.08), rgba(0,180,216,0.08))',
2899
- border: 'rgba(0,119,182,0.15)',
2900
- shadow: 'rgba(0,119,182,0.12)',
2901
- inputBackground: '#f0f9ff',
2902
- inputBorder: '#bae6fd'
2903
- }
2904
- },
2905
- TWILIGHT: {
2906
- colors: {
2907
- primary: '#9333ea',
2908
- primaryLight: '#a855f7',
2909
- primaryDark: '#7e22ce',
2910
- secondary: '#ec4899',
2911
- background: '#ffffff',
2912
- backgroundGradient: '#faf5ff',
2913
- text: '#1e293b',
2914
- textSecondary: '#64748b',
2915
- userBubble: 'linear-gradient(135deg, #9333ea, #ec4899)',
2916
- aiBubble: '#ffffff',
2917
- headerGradient: 'linear-gradient(90deg, rgba(147,51,234,0.08), rgba(236,72,153,0.08))',
2918
- border: 'rgba(147,51,234,0.15)',
2919
- shadow: 'rgba(147,51,234,0.12)',
2920
- inputBackground: '#faf5ff',
2921
- inputBorder: '#e9d5ff'
2922
- }
2923
- },
2924
- MINT: {
2925
- colors: {
2926
- primary: '#14b8a6',
2927
- primaryLight: '#2dd4bf',
2928
- primaryDark: '#0d9488',
2929
- secondary: '#06b6d4',
2930
- background: '#ffffff',
2931
- backgroundGradient: '#f0fdfa',
2932
- text: '#1e293b',
2933
- textSecondary: '#64748b',
2934
- userBubble: 'linear-gradient(135deg, #14b8a6, #2dd4bf)',
2935
- aiBubble: '#ffffff',
2936
- headerGradient: 'linear-gradient(90deg, rgba(20,184,166,0.08), rgba(6,182,212,0.08))',
2937
- border: 'rgba(20,184,166,0.15)',
2938
- shadow: 'rgba(20,184,166,0.12)',
2939
- inputBackground: '#f0fdfa',
2940
- inputBorder: '#99f6e4'
2941
- }
2942
- },
2943
- ROSE: {
2944
- colors: {
2945
- primary: '#e11d48',
2946
- primaryLight: '#fb7185',
2947
- primaryDark: '#be123c',
2948
- secondary: '#f43f5e',
2949
- background: '#ffffff',
2950
- backgroundGradient: '#fff1f2',
2951
- text: '#1e293b',
2952
- textSecondary: '#64748b',
2953
- userBubble: 'linear-gradient(135deg, #e11d48, #fb7185)',
2954
- aiBubble: '#ffffff',
2955
- headerGradient: 'linear-gradient(90deg, rgba(225,29,72,0.08), rgba(244,63,94,0.08))',
2956
- border: 'rgba(225,29,72,0.15)',
2957
- shadow: 'rgba(225,29,72,0.12)',
2958
- inputBackground: '#fff1f2',
2959
- inputBorder: '#fecdd3'
2960
- }
2961
- },
2962
- AURORA: {
2963
- colors: {
2964
- primary: '#0ea5e9',
2965
- primaryLight: '#38bdf8',
2966
- primaryDark: '#0284c7',
2967
- secondary: '#10b981',
2968
- background: '#ffffff',
2969
- backgroundGradient: '#f0f9ff',
2970
- text: '#1e293b',
2971
- textSecondary: '#64748b',
2972
- userBubble: 'linear-gradient(135deg, #0ea5e9, #10b981)',
2973
- aiBubble: '#ffffff',
2974
- headerGradient: 'linear-gradient(90deg, rgba(14,165,233,0.08), rgba(16,185,129,0.08))',
2975
- border: 'rgba(14,165,233,0.15)',
2976
- shadow: 'rgba(14,165,233,0.12)',
2977
- inputBackground: '#f0f9ff',
2978
- inputBorder: '#bae6fd'
2979
- }
2980
- },
2981
- LAVENDER: {
2982
- colors: {
2983
- primary: '#8b5cf6',
2984
- primaryLight: '#a78bfa',
2985
- primaryDark: '#7c3aed',
2986
- secondary: '#c084fc',
2987
- background: '#ffffff',
2988
- backgroundGradient: '#faf5ff',
2989
- text: '#1e293b',
2990
- textSecondary: '#64748b',
2991
- userBubble: 'linear-gradient(135deg, #8b5cf6, #c084fc)',
2992
- aiBubble: '#ffffff',
2993
- headerGradient: 'linear-gradient(90deg, rgba(139,92,246,0.08), rgba(192,132,252,0.08))',
2994
- border: 'rgba(139,92,246,0.15)',
2995
- shadow: 'rgba(139,92,246,0.12)',
2996
- inputBackground: '#faf5ff',
2997
- inputBorder: '#ddd6fe'
2998
- }
2999
- },
3000
- CORAL: {
3001
- colors: {
3002
- primary: '#f97316',
3003
- primaryLight: '#fb923c',
3004
- primaryDark: '#ea580c',
3005
- secondary: '#f43f5e',
3006
- background: '#ffffff',
3007
- backgroundGradient: '#fff7ed',
3008
- text: '#1e293b',
3009
- textSecondary: '#64748b',
3010
- userBubble: 'linear-gradient(135deg, #f97316, #fb923c)',
3011
- aiBubble: '#ffffff',
3012
- headerGradient: 'linear-gradient(90deg, rgba(249,115,22,0.08), rgba(244,63,94,0.08))',
3013
- border: 'rgba(249,115,22,0.15)',
3014
- shadow: 'rgba(249,115,22,0.12)',
3015
- inputBackground: '#fff7ed',
3016
- inputBorder: '#fed7aa'
3017
- }
3018
- },
3019
- JADE: {
3020
- colors: {
3021
- primary: '#059669',
3022
- primaryLight: '#10b981',
3023
- primaryDark: '#047857',
3024
- secondary: '#34d399',
3025
- background: '#ffffff',
3026
- backgroundGradient: '#f0fdf4',
3027
- text: '#1e293b',
3028
- textSecondary: '#64748b',
3029
- userBubble: 'linear-gradient(135deg, #059669, #10b981)',
3030
- aiBubble: '#ffffff',
3031
- headerGradient: 'linear-gradient(90deg, rgba(5,150,105,0.08), rgba(52,211,153,0.08))',
3032
- border: 'rgba(5,150,105,0.15)',
3033
- shadow: 'rgba(5,150,105,0.12)',
3034
- inputBackground: '#f0fdf4',
3035
- inputBorder: '#bbf7d0'
3036
- }
3037
- },
3038
- STARSKY: {
3039
- colors: {
3040
- primary: '#6366f1',
3041
- primaryLight: '#818cf8',
3042
- primaryDark: '#4f46e5',
3043
- secondary: '#a855f7',
3044
- background: '#0f172a',
3045
- backgroundGradient: '#1e1b4b',
3046
- text: '#e2e8f0',
3047
- textSecondary: '#94a3b8',
3048
- userBubble: 'linear-gradient(135deg, #6366f1, #a855f7)',
3049
- aiBubble: '#1e1b4b',
3050
- headerGradient: 'linear-gradient(90deg, rgba(99,102,241,0.15), rgba(168,85,247,0.15))',
3051
- border: 'rgba(99,102,241,0.3)',
3052
- shadow: 'rgba(0,0,0,0.3)',
3053
- inputBackground: '#1e1b4b',
3054
- inputBorder: '#312e81'
3055
- }
3056
- },
3057
- SUNSET: {
3058
- colors: {
3059
- primary: '#ea580c',
3060
- primaryLight: '#f97316',
3061
- primaryDark: '#c2410c',
3062
- secondary: '#dc2626',
3063
- background: '#ffffff',
3064
- backgroundGradient: '#fff8f0',
3065
- text: '#1e293b',
3066
- textSecondary: '#64748b',
3067
- userBubble: 'linear-gradient(135deg, #ea580c, #dc2626)',
3068
- aiBubble: '#ffffff',
3069
- headerGradient: 'linear-gradient(90deg, rgba(234,88,12,0.08), rgba(220,38,38,0.08))',
3070
- border: 'rgba(234,88,12,0.15)',
3071
- shadow: 'rgba(234,88,12,0.12)',
3072
- inputBackground: '#fff8f0',
3073
- inputBorder: '#fed7aa'
3074
- }
3075
- }
3076
- };
3077
3616
  class AIChatDialog extends HTMLElement {
3078
3617
  static get observedAttributes() {
3079
3618
  return ['visible'];
@@ -3244,6 +3783,8 @@ class AIChatDialog extends HTMLElement {
3244
3783
  // P2-17: 应用移动端/桌面端布局(自动全屏或恢复浮动气泡)
3245
3784
  _applyMobileLayout() {
3246
3785
  if (!this._dialog) return;
3786
+ // 行内嵌入模式跳过,保持 CSS 控制的布局
3787
+ if (this.getAttribute('mode') === 'inline') return;
3247
3788
  if (this._isMobile) {
3248
3789
  // 移动端:强制全屏(与Vue版 dialogStyle 一致)
3249
3790
  this._dialog.style.width = '100vw';
@@ -3505,11 +4046,11 @@ class AIChatDialog extends HTMLElement {
3505
4046
  /* ====== 对话框主体(与Vue .ai-chat-dialog 完全一致) ====== */
3506
4047
  .ai-chat-dialog {
3507
4048
  position: fixed;
3508
- top: 96px;
3509
- right: 24px;
4049
+ top: var(--ai-dialog-top, 96px);
4050
+ right: var(--ai-dialog-right, 24px);
3510
4051
  bottom: auto;
3511
- width: min(420px, calc(100vw - 48px));
3512
- height: min(640px, 80vh);
4052
+ width: var(--ai-dialog-width, min(420px, calc(100vw - 48px)));
4053
+ height: var(--ai-dialog-height, min(640px, 80vh));
3513
4054
  background: var(--ai-bg);
3514
4055
  border-radius: 16px;
3515
4056
  border: 1px solid rgba(226, 232, 240, 0.78);
@@ -4499,6 +5040,27 @@ class AIChatDialog extends HTMLElement {
4499
5040
  .action-icon { width: 30px; height: 30px; }
4500
5041
  }
4501
5042
 
5043
+ /* ========== 行内嵌入模式(mode="inline",挂载到用户指定容器) ========== */
5044
+ :host([mode="inline"]) { position: relative; top: auto; right: auto; bottom: auto; z-index: auto; width: 100%; height: 100%; }
5045
+ :host([mode="inline"]) .ai-float-container { height: 100%; }
5046
+ :host([mode="inline"]) .float-button { display: none; }
5047
+ :host([mode="inline"]) .ai-chat-dialog {
5048
+ position: relative;
5049
+ top: auto;
5050
+ right: auto;
5051
+ width: 100%;
5052
+ height: 100%;
5053
+ border-radius: 0;
5054
+ box-shadow: none;
5055
+ border: 1px solid var(--ai-border);
5056
+ opacity: 1;
5057
+ transform: none;
5058
+ pointer-events: auto;
5059
+ }
5060
+ :host([mode="inline"]) .dialog-header { cursor: default; }
5061
+ :host([mode="inline"]) .close-btn,
5062
+ :host([mode="inline"]) .expand-btn { display: none; }
5063
+
4502
5064
  /* ========== 暗色主题覆盖(theme: 'dark') ========== */
4503
5065
  :host(.dark-theme) .ai-chat-dialog {
4504
5066
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.3);
@@ -4644,8 +5206,8 @@ class AIChatDialog extends HTMLElement {
4644
5206
  });
4645
5207
  }
4646
5208
 
4647
- // 拖拽
4648
- if (this._dialog && this._config?.enableDrag !== false) this.initDraggable();
5209
+ // 拖拽(内嵌模式禁用)
5210
+ if (this._dialog && this._config?.enableDrag !== false && this.getAttribute('mode') !== 'inline') this.initDraggable();
4649
5211
  });
4650
5212
  }
4651
5213
 
@@ -5246,10 +5808,20 @@ class AIChatDialog extends HTMLElement {
5246
5808
  }));
5247
5809
  this.setLoading(true);
5248
5810
  try {
5811
+ // 上传附件并收集 attachmentId
5812
+ const attachmentIds = [];
5249
5813
  for (const file of attachments) {
5250
- await this.uploadAttachment(file).catch(err => console.warn('[AIChatDialog] 附件上传失败:', err));
5814
+ const res = await this.uploadAttachment(file).catch(err => {
5815
+ console.warn('[AIChatDialog] 附件上传失败:', err);
5816
+ return null;
5817
+ });
5818
+ if (res?.success && res.data?.attachmentId) {
5819
+ attachmentIds.push(res.data.attachmentId);
5820
+ }
5251
5821
  }
5252
- await this.sendMessageToAI(content || attachmentText);
5822
+ await this.sendMessageToAI(content || attachmentText, {
5823
+ attachmentIds
5824
+ });
5253
5825
  } catch (err) {
5254
5826
  console.error('[AIChatDialog] Error:', err);
5255
5827
  this.handleError(err);
@@ -5278,7 +5850,11 @@ class AIChatDialog extends HTMLElement {
5278
5850
  this._streaming = true;
5279
5851
  this.setLoading(false); // 关掉全局 loading,用消息级 loading 替代
5280
5852
  this.updateLoadingUI(); // re-lock input via _streaming flag
5281
- await this._directApiCallStream(msgId, content, options.streamOptions || {});
5853
+ const streamOpts = {
5854
+ ...(options.streamOptions || {})
5855
+ };
5856
+ if (options.attachmentIds?.length) streamOpts.attachmentIds = options.attachmentIds;
5857
+ await this._directApiCallStream(msgId, content, streamOpts);
5282
5858
  }
5283
5859
  }
5284
5860
  async mockResponse(userContent) {
@@ -5345,6 +5921,7 @@ class AIChatDialog extends HTMLElement {
5345
5921
  const response = await this._chatClient.sendMessageStream(content, {
5346
5922
  onMessage: chunk => {
5347
5923
  if (!this._isPlaceholder(chunk) && !this._isEventLike(chunk)) {
5924
+ if (!chunk) chunk = '\n';
5348
5925
  streamText += chunk;
5349
5926
  this._updateMsg(msgId, streamText);
5350
5927
  }
@@ -5564,7 +6141,7 @@ class AIChatDialog extends HTMLElement {
5564
6141
  this._messages[idx].content = content;
5565
6142
  delete this._messages[idx]._isStreaming;
5566
6143
  this._messages[idx].time = this.formatTime();
5567
- this._messages[idx]._status = content && !content.startsWith('(') ? 'completed' : 'error';
6144
+ this._messages[idx]._status = this._isErrorContent(content) ? 'error' : 'completed';
5568
6145
  if (this._streamTypeRaf) {
5569
6146
  cancelAnimationFrame(this._streamTypeRaf);
5570
6147
  this._streamTypeRaf = null;
@@ -5580,6 +6157,7 @@ class AIChatDialog extends HTMLElement {
5580
6157
  // 运行时占位符过滤(对齐 portal)
5581
6158
  _isPlaceholder(text) {
5582
6159
  if (!text || typeof text !== 'string') return false;
6160
+ if (text === '\n' || text === '\n\n') return false;
5583
6161
  const p = text.trim();
5584
6162
  if (!p) return true;
5585
6163
  return RUNTIME_PLACEHOLDERS.some(k => p.includes(k));
@@ -5595,6 +6173,13 @@ class AIChatDialog extends HTMLElement {
5595
6173
  return false;
5596
6174
  }
5597
6175
 
6176
+ // 判断错误标记内容(替换脆弱的前缀检查 startsWith('('))
6177
+ _ERROR_CONTENT_PATTERNS = ['(请求超时', '(等待AI处理', '(无回复)', '(已停止)', '(AI 处理超时', '错误:', '网络错误:', '抱歉,'];
6178
+ _isErrorContent(content) {
6179
+ if (!content) return true;
6180
+ return this._ERROR_CONTENT_PATTERNS.some(p => content.startsWith(p));
6181
+ }
6182
+
5598
6183
  // 运行时事件管理 – incremental DOM, no renderMessages
5599
6184
  _addRuntimeEvent(msgId, event) {
5600
6185
  const idx = this._messages.findIndex(m => m.id === msgId);
@@ -5603,8 +6188,6 @@ class AIChatDialog extends HTMLElement {
5603
6188
  const last = this._messages[idx]._runtimeEvents[this._messages[idx]._runtimeEvents.length - 1];
5604
6189
  if (last && last._text === event._text) return;
5605
6190
  this._messages[idx]._runtimeEvents.push(event);
5606
- !['NODE_COMPLETE', 'TOOL_END', 'TOOL_RESULT'].includes(event._type);
5607
-
5608
6191
  // Path 1: panel DOM exists and is alive – incremental append
5609
6192
  if (this._runtimeEventsContainerEl && this._body.contains(this._runtimeEventsContainerEl)) {
5610
6193
  const row = document.createElement('div');
@@ -5975,6 +6558,9 @@ class AIChatDialog extends HTMLElement {
5975
6558
  parseMarkdown(text) {
5976
6559
  if (!text) return '';
5977
6560
  try {
6561
+ // 逐行规范化标题:确保 # 后跟空格(如 "####4.2" → "#### 4.2")
6562
+ const lines = text.split('\n');
6563
+ text = lines.map(line => line.replace(/^(\s{0,3}#{1,6})([^\s#].*)$/, '$1 $2')).join('\n');
5978
6564
  // marked 解析 markdown
5979
6565
  const rawHtml = g.parse(text);
5980
6566
  // DOMPurify 净化HTML(防止XSS攻击)
@@ -6002,7 +6588,7 @@ if (typeof window !== 'undefined') {
6002
6588
  * 支持任意前端框架:Vue, React, Angular, 原生HTML等
6003
6589
  *
6004
6590
  * @author IBC AI Team
6005
- * @version 2.0.0
6591
+ * @version 2.0.4
6006
6592
  */
6007
6593
 
6008
6594
 
@@ -6014,16 +6600,53 @@ function createAIChatDialog(options = {}) {
6014
6600
  // 设置属性
6015
6601
  if (options.title) dialog.setAttribute('title', options.title);
6016
6602
  if (options.placeholder) dialog.setAttribute('placeholder', options.placeholder);
6017
- if (options.width) dialog.style.setProperty('--dialog-width', `${options.width}px`);
6018
- if (options.height) dialog.style.setProperty('--dialog-height', `${options.height}px`);
6019
-
6020
- // 添加到DOM(隐藏状态)
6021
- document.body.appendChild(dialog);
6603
+ // 对话框尺寸和位置(浮窗模式可用)
6604
+ if (options.width) dialog.style.setProperty('--ai-dialog-width', typeof options.width === 'number' ? `${options.width}px` : options.width);
6605
+ if (options.height) dialog.style.setProperty('--ai-dialog-height', typeof options.height === 'number' ? `${options.height}px` : options.height);
6606
+ if (options.top != null) dialog.style.setProperty('--ai-dialog-top', typeof options.top === 'number' ? `${options.top}px` : options.top);
6607
+ if (options.right != null) dialog.style.setProperty('--ai-dialog-right', typeof options.right === 'number' ? `${options.right}px` : options.right);
6608
+
6609
+ // 挂载到指定容器或 body
6610
+ if (options.target) {
6611
+ const container = typeof options.target === 'string' ? document.querySelector(options.target) : options.target;
6612
+ if (container) {
6613
+ dialog.setAttribute('mode', 'inline');
6614
+ container.appendChild(dialog);
6615
+ } else {
6616
+ console.warn('[AI Web SDK] target 容器未找到,回退到 body');
6617
+ document.body.appendChild(dialog);
6618
+ }
6619
+ } else {
6620
+ document.body.appendChild(dialog);
6621
+ }
6022
6622
 
6023
6623
  // 初始化配置
6024
6624
  if (Object.keys(options).length > 0) {
6025
6625
  dialog.init(options);
6026
6626
  }
6627
+
6628
+ // 行内模式:挂载到 DOM 后直接展开
6629
+ if (options.target) {
6630
+ requestAnimationFrame(() => {
6631
+ dialog.style.position = 'relative';
6632
+ dialog.style.height = '100%';
6633
+ if (dialog.shadowRoot) {
6634
+ const container = dialog.shadowRoot.querySelector('.ai-float-container');
6635
+ const dialogEl = dialog.shadowRoot.querySelector('.ai-chat-dialog');
6636
+ const btn = dialog.shadowRoot.querySelector('.float-button');
6637
+ if (container) container.style.height = '100%';
6638
+ if (btn) btn.style.display = 'none';
6639
+ if (dialogEl) {
6640
+ dialogEl.style.position = 'relative';
6641
+ dialogEl.style.top = 'auto';
6642
+ dialogEl.style.right = 'auto';
6643
+ dialogEl.style.width = '100%';
6644
+ dialogEl.style.height = '100%';
6645
+ dialogEl.classList.add('dialog-visible');
6646
+ }
6647
+ }
6648
+ });
6649
+ }
6027
6650
  return dialog;
6028
6651
  }
6029
6652
 
@@ -6208,14 +6831,14 @@ var index = {
6208
6831
  createAIChatDialog,
6209
6832
  installVuePlugin,
6210
6833
  useAIChat,
6211
- version: '2.0.0'
6834
+ version: '2.0.4'
6212
6835
  };
6213
6836
 
6214
6837
  // 全局暴露(UMD/浏览器环境)
6215
6838
  if (typeof window !== 'undefined') {
6216
6839
  window.AICreateChatDialog = createAIChatDialog;
6217
6840
  window.AIWebSDK = {
6218
- version: '2.0.0',
6841
+ version: '2.0.4',
6219
6842
  create: createAIChatDialog,
6220
6843
  AIChatDialog,
6221
6844
  AIChatClient,