@anker-in/campaign-ui 0.2.11-beta.40 → 0.2.11-beta.42

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.
Files changed (54) hide show
  1. package/dist/cjs/components/LiveChatWidget/LiveChatWidget.js +1 -1
  2. package/dist/cjs/components/LiveChatWidget/LiveChatWidget.js.map +3 -3
  3. package/dist/cjs/components/LiveChatWidget/api/chat.js +2 -2
  4. package/dist/cjs/components/LiveChatWidget/api/chat.js.map +3 -3
  5. package/dist/cjs/components/LiveChatWidget/components/ComplianceDialog.js +6 -6
  6. package/dist/cjs/components/LiveChatWidget/components/ComplianceDialog.js.map +2 -2
  7. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductCard.d.ts +1 -1
  8. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductCard.js +1 -1
  9. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductCard.js.map +3 -3
  10. package/dist/cjs/components/LiveChatWidget/components/MessageList.js +3 -3
  11. package/dist/cjs/components/LiveChatWidget/components/MessageList.js.map +3 -3
  12. package/dist/cjs/components/LiveChatWidget/hooks/useChatState.d.ts +4 -2
  13. package/dist/cjs/components/LiveChatWidget/hooks/useChatState.js +1 -1
  14. package/dist/cjs/components/LiveChatWidget/hooks/useChatState.js.map +3 -3
  15. package/dist/cjs/components/LiveChatWidget/types.d.ts +18 -11
  16. package/dist/cjs/components/LiveChatWidget/types.js.map +1 -1
  17. package/dist/cjs/components/index.d.ts +1 -1
  18. package/dist/cjs/components/index.js +1 -1
  19. package/dist/cjs/components/index.js.map +2 -2
  20. package/dist/cjs/stories/LiveChatWidget.stories.d.ts +1 -109
  21. package/dist/cjs/stories/LiveChatWidget.stories.js +7 -166
  22. package/dist/cjs/stories/LiveChatWidget.stories.js.map +3 -3
  23. package/dist/esm/components/LiveChatWidget/LiveChatWidget.js +1 -1
  24. package/dist/esm/components/LiveChatWidget/LiveChatWidget.js.map +3 -3
  25. package/dist/esm/components/LiveChatWidget/api/chat.js +2 -2
  26. package/dist/esm/components/LiveChatWidget/api/chat.js.map +3 -3
  27. package/dist/esm/components/LiveChatWidget/components/ComplianceDialog.js +7 -7
  28. package/dist/esm/components/LiveChatWidget/components/ComplianceDialog.js.map +2 -2
  29. package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductCard.d.ts +1 -1
  30. package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductCard.js +1 -1
  31. package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductCard.js.map +3 -3
  32. package/dist/esm/components/LiveChatWidget/components/MessageList.js +2 -2
  33. package/dist/esm/components/LiveChatWidget/components/MessageList.js.map +3 -3
  34. package/dist/esm/components/LiveChatWidget/hooks/useChatState.d.ts +4 -2
  35. package/dist/esm/components/LiveChatWidget/hooks/useChatState.js +1 -1
  36. package/dist/esm/components/LiveChatWidget/hooks/useChatState.js.map +3 -3
  37. package/dist/esm/components/LiveChatWidget/types.d.ts +18 -11
  38. package/dist/esm/components/index.d.ts +1 -1
  39. package/dist/esm/components/index.js +1 -1
  40. package/dist/esm/components/index.js.map +2 -2
  41. package/dist/esm/stories/LiveChatWidget.stories.d.ts +1 -109
  42. package/dist/esm/stories/LiveChatWidget.stories.js +7 -166
  43. package/dist/esm/stories/LiveChatWidget.stories.js.map +3 -3
  44. package/package.json +1 -1
  45. package/src/components/LiveChatWidget/LiveChatWidget.tsx +65 -23
  46. package/src/components/LiveChatWidget/api/chat.ts +8 -7
  47. package/src/components/LiveChatWidget/components/ComplianceDialog.tsx +1 -5
  48. package/src/components/LiveChatWidget/components/MessageContent/ProductCard.tsx +17 -8
  49. package/src/components/LiveChatWidget/components/MessageList.tsx +11 -17
  50. package/src/components/LiveChatWidget/hooks/useChatState.ts +64 -98
  51. package/src/components/LiveChatWidget/types.ts +18 -11
  52. package/src/components/index.ts +2 -1
  53. package/src/stories/LiveChatWidget.stories.tsx +95 -660
  54. package/src/styles/livechat.css +29 -0
@@ -143,10 +143,19 @@ export const MessageList: React.FC<MessageListProps> = ({
143
143
  // 监听滚动事件,控制按钮显示
144
144
  useEffect(() => {
145
145
  const container = listRef.current
146
+ console.log('[MessageList] useEffect - container:', container)
146
147
  if (!container) return
147
148
 
148
149
  const handleScroll = () => {
149
- setShowScrollButton(!isNearBottom())
150
+ const nearBottom = isNearBottom()
151
+ console.log('[MessageList] handleScroll:', {
152
+ scrollTop: container.scrollTop,
153
+ scrollHeight: container.scrollHeight,
154
+ clientHeight: container.clientHeight,
155
+ isNearBottom: nearBottom,
156
+ willShowButton: !nearBottom,
157
+ })
158
+ setShowScrollButton(!nearBottom)
150
159
  }
151
160
 
152
161
  // 初始检查
@@ -223,22 +232,7 @@ export const MessageList: React.FC<MessageListProps> = ({
223
232
  {/* 回到底部按钮 */}
224
233
  <button
225
234
  onClick={scrollToBottom}
226
- className={`flex -translate-x-1/2 items-center justify-center ${showScrollButton ? '' : 'pointer-events-none'}`}
227
- style={{
228
- position: 'absolute',
229
- bottom: '24px',
230
- left: '50%',
231
- zIndex: 10,
232
- width: '40px',
233
- height: '40px',
234
- borderRadius: '50%',
235
- backgroundColor: 'rgba(255, 255, 255, 0.95)',
236
- boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
237
- transition: 'all 300ms ease-in-out',
238
- opacity: showScrollButton ? 1 : 0,
239
- cursor: 'pointer',
240
- border: 'none',
241
- }}
235
+ className={`livechat-scroll-to-bottom ${showScrollButton ? 'visible' : 'hidden'}`}
242
236
  aria-label="Scroll to bottom"
243
237
  aria-hidden={!showScrollButton}
244
238
  >
@@ -20,8 +20,8 @@ import { transformCartData } from '../utils/cartTransformers'
20
20
  * 处理缓冲区中的文本,检测完整的 {{product:xxx}} 占位符
21
21
  *
22
22
  * @param buffer 当前缓冲区内容(包含新接收的文本)
23
- * @param productMap shopifyId → Product 的映射表
24
- * @param rawProductMap shopifyId → raw backend product 的映射表
23
+ * @param productMap handle → Product 的映射表
24
+ * @param rawProductMap handle → raw backend product 的映射表
25
25
  * @param onAddToCart 添加到购物车回调
26
26
  * @param productCardRender 自定义产品卡片渲染函数
27
27
  * @returns { contents: 需要添加的内容数组, remainingBuffer: 剩余缓冲区内容 }
@@ -31,7 +31,7 @@ function parseStreamingText(
31
31
  productMap: Map<string, Product>,
32
32
  rawProductMap: Map<string, any>,
33
33
  onAddToCart?: (product: Product) => void,
34
- productCardRender?: (product: any) => React.ReactNode
34
+ productCardRender?: (product: any, productHandle: string) => React.ReactNode
35
35
  ): { contents: MessageContent[]; remainingBuffer: string } {
36
36
  const contents: MessageContent[] = []
37
37
  const regex = /\{\{(?:product:)?([^}]+)\}\}/g
@@ -55,22 +55,24 @@ function parseStreamingText(
55
55
  const product = productMap.get(productId)
56
56
  const rawProduct = rawProductMap.get(productId)
57
57
 
58
+ // 无论是否找到产品数据,都渲染 product_card,应用层可通过 productHandle 查询产品
58
59
  if (product) {
59
60
  console.log('[useChatState] 🎯 实时检测到产品:', productId, '→', product.title)
60
- contents.push({
61
- type: 'product_card',
62
- data: {
63
- product: product,
64
- rawProduct: rawProduct,
65
- onAddToCart: onAddToCart,
66
- productCardRender: productCardRender
67
- }
68
- } as ProductCardContent)
69
61
  } else {
70
- // 产品未找到,隐藏产品占位符(不在前端展示)
71
- console.warn('[useChatState] ⚠️ 实时解析未找到产品,已隐藏:', productId)
62
+ console.log('[useChatState] 📦 实时检测到产品占位符,产品数据待应用层查询:', productId)
72
63
  }
73
64
 
65
+ contents.push({
66
+ type: 'product_card',
67
+ data: {
68
+ product: product,
69
+ rawProduct: rawProduct,
70
+ productHandle: productId,
71
+ onAddToCart: onAddToCart,
72
+ productCardRender: productCardRender
73
+ }
74
+ } as ProductCardContent)
75
+
74
76
  lastIndex = regex.lastIndex
75
77
  }
76
78
 
@@ -102,18 +104,19 @@ function parseStreamingText(
102
104
  }
103
105
 
104
106
  /**
105
- * 解析文本中的 {{shopifyId}},返回 [text, product_card, text, ...] 数组(用于历史消息重组)
107
+ * 解析文本中的 {{handle}},返回 [text, product_card, text, ...] 数组(用于历史消息重组)
106
108
  *
107
- * @param text 包含 {{shopifyId}} 标记的文本
108
- * @param productMap shopifyId → Product 的映射表
109
+ * @param text 包含 {{handle}} 标记的文本
110
+ * @param productMap handle → Product 的映射表
111
+ * @param rawProductMap handle → raw backend product 的映射表
109
112
  * @param onAddToCart 添加到购物车回调
110
113
  * @param productCardRender 自定义产品卡片渲染函数
111
114
  * @returns MessageContent 数组
112
115
  *
113
116
  * @example
114
117
  * 输入:
115
- * text: "我推荐以下产品:\n{{12345}}\n这款产品性价比很高。"
116
- * productMap: Map { '12345' => Product {...} }
118
+ * text: "我推荐以下产品:\n{{product-handle}}\n这款产品性价比很高。"
119
+ * productMap: Map { 'product-handle' => Product {...} }
117
120
  * 输出:
118
121
  * [
119
122
  * { type: 'text', text: '我推荐以下产品:' },
@@ -126,7 +129,7 @@ function parseTextWithProductIds(
126
129
  productMap: Map<string, Product>,
127
130
  rawProductMap: Map<string, any>,
128
131
  onAddToCart?: (product: Product) => void,
129
- productCardRender?: (product: any) => React.ReactNode
132
+ productCardRender?: (product: any, productHandle: string) => React.ReactNode
130
133
  ): MessageContent[] {
131
134
  const result: MessageContent[] = []
132
135
  // 修改正则表达式以匹配 {{product:ID}} 格式
@@ -149,25 +152,26 @@ function parseTextWithProductIds(
149
152
  } as TextContent)
150
153
  }
151
154
 
152
- // 添加产品卡片
155
+ // 添加产品卡片(无论是否找到产品数据,都渲染 product_card)
153
156
  const product = productMap.get(productId)
154
157
  const rawProduct = rawProductMap.get(productId)
155
158
  if (product) {
156
159
  console.log(`[useChatState] ✅ 找到产品匹配: ${productId} → ${product.title}`)
157
- result.push({
158
- type: 'product_card',
159
- data: {
160
- product: product,
161
- rawProduct: rawProduct,
162
- onAddToCart: onAddToCart,
163
- productCardRender: productCardRender,
164
- },
165
- } as ProductCardContent)
166
160
  } else {
167
- // 找不到产品时,隐藏产品占位符(不在前端展示)
168
- console.warn(`[useChatState] ❌ Product not found for ID: "${productId}",已隐藏`)
161
+ console.log(`[useChatState] 📦 产品占位符,产品数据待应用层查询: ${productId}`)
169
162
  }
170
163
 
164
+ result.push({
165
+ type: 'product_card',
166
+ data: {
167
+ product: product,
168
+ rawProduct: rawProduct,
169
+ productHandle: productId,
170
+ onAddToCart: onAddToCart,
171
+ productCardRender: productCardRender,
172
+ },
173
+ } as ProductCardContent)
174
+
171
175
  lastIndex = regex.lastIndex
172
176
  }
173
177
 
@@ -184,16 +188,17 @@ function parseTextWithProductIds(
184
188
  }
185
189
 
186
190
  /**
187
- * 重组消息内容:解析文本中的 {{shopifyId}},替换为产品卡片
191
+ * 重组消息内容:解析文本中的 {{handle}},替换为产品卡片
188
192
  *
189
193
  * 处理逻辑:
190
194
  * 1. 遍历消息的所有 content blocks
191
- * 2. 对于 text 类型,解析其中的 {{shopifyId}} 并拆分为多个 content
195
+ * 2. 对于 text 类型,解析其中的 {{handle}} 并拆分为多个 content
192
196
  * 3. 跳过 product_list 类型(已经被拆分到文本中)
193
197
  * 4. 其他类型直接保留
194
198
  *
195
199
  * @param contents 原始消息内容数组
196
- * @param productMap shopifyId → Product 的映射表
200
+ * @param productMap handle → Product 的映射表
201
+ * @param rawProductMap handle → raw backend product 的映射表
197
202
  * @param onAddToCart 添加到购物车回调
198
203
  * @param productCardRender 自定义产品卡片渲染函数
199
204
  * @returns 重组后的消息内容数组
@@ -203,7 +208,7 @@ function reorganizeMessageContent(
203
208
  productMap: Map<string, Product>,
204
209
  rawProductMap: Map<string, any>,
205
210
  onAddToCart?: (product: Product) => void,
206
- productCardRender?: (product: any) => React.ReactNode
211
+ productCardRender?: (product: any, productHandle: string) => React.ReactNode
207
212
  ): MessageContent[] {
208
213
  const result: MessageContent[] = []
209
214
 
@@ -229,7 +234,7 @@ function reorganizeMessageContent(
229
234
 
230
235
  /**
231
236
  * 处理单条消息的重组(用于历史消息加载)
232
- * 如果消息包含 product_list 和带有 {{}} 的文本,则进行重组
237
+ * 如果消息包含带有 {{}} 的文本,则进行重组
233
238
  *
234
239
  * @param message 原始消息
235
240
  * @param onAddToCart 添加到购物车回调
@@ -239,14 +244,8 @@ function reorganizeMessageContent(
239
244
  function maybeReorganizeHistoricalMessage(
240
245
  message: Message,
241
246
  onAddToCart?: (product: Product) => void,
242
- productCardRender?: (product: any) => React.ReactNode
247
+ productCardRender?: (product: any, productHandle: string) => React.ReactNode
243
248
  ): Message {
244
- // 检查消息是否包含 product_list
245
- const hasProductList = message.content.some(c => c.type === 'product_list')
246
- if (!hasProductList) {
247
- return message // 没有 product_list,不需要重组
248
- }
249
-
250
249
  // 检查消息是否包含带有 {{}} 的文本
251
250
  const hasPlaceholder = message.content.some(
252
251
  c => c.type === 'text' && /\{\{(?:product:)?[^}]+\}\}/.test((c as TextContent).text)
@@ -257,9 +256,9 @@ function maybeReorganizeHistoricalMessage(
257
256
 
258
257
  console.log('[useChatState] 检测到历史消息需要重组, 消息ID:', message.id)
259
258
 
260
- // 构建产品映射
259
+ // 构建产品映射 (handle → Product)
261
260
  const productMap = new Map<string, Product>()
262
- // 从 structured_content 中提取原始后端产品数据
261
+ // 从 structured_content 中提取原始后端产品数据 (handle → rawProduct)
263
262
  const rawProductMap = new Map<string, any>()
264
263
 
265
264
  // 优先从 structured_content 获取原始产品数据(如果存在)
@@ -267,22 +266,9 @@ function maybeReorganizeHistoricalMessage(
267
266
  message.structured_content.forEach(structuredContent => {
268
267
  if (structuredContent.type === 'product_list' && Array.isArray(structuredContent.data)) {
269
268
  structuredContent.data.forEach((rawProduct: any) => {
270
- if (rawProduct && rawProduct.shopify_product_id) {
271
- const shopifyId = rawProduct.shopify_product_id
272
- // 1. 使用完整的 shopifyId 作为key
273
- rawProductMap.set(shopifyId, rawProduct)
274
-
275
- // 2. 同时提取数字部分作为key
276
- const numericId = shopifyId.match(/\d+$/)?.[0]
277
- if (numericId) {
278
- rawProductMap.set(numericId, rawProduct)
279
- }
280
-
281
- console.log('[useChatState] 从 structured_content 提取原始产品数据:', {
282
- fullId: shopifyId,
283
- numericId,
284
- title: rawProduct.title,
285
- })
269
+ if (rawProduct && rawProduct.handle) {
270
+ rawProductMap.set(rawProduct.handle, rawProduct)
271
+ console.log('[useChatState] structured_content 提取原始产品数据, handle:', rawProduct.handle)
286
272
  }
287
273
  })
288
274
  }
@@ -294,15 +280,8 @@ function maybeReorganizeHistoricalMessage(
294
280
  if (content.type === 'product_list') {
295
281
  const productListContent = content as ProductListContent
296
282
  productListContent.data.products.forEach(product => {
297
- if (product && product.shopifyId) {
298
- // 1. 使用完整的 shopifyId 作为key
299
- productMap.set(product.shopifyId, product)
300
-
301
- // 2. 同时提取数字部分作为key
302
- const numericId = product.shopifyId.match(/\d+$/)?.[0]
303
- if (numericId) {
304
- productMap.set(numericId, product)
305
- }
283
+ if (product && product.handle) {
284
+ productMap.set(product.handle, product)
306
285
  }
307
286
  })
308
287
  }
@@ -393,8 +372,10 @@ export interface UseChatStateOptions {
393
372
 
394
373
  /**
395
374
  * 自定义产品卡片渲染函数
375
+ * @param product 产品数据(如果在 product_list 中找到),否则为 undefined
376
+ * @param productHandle 文本占位符中的产品 ID,可用于应用层查询产品数据
396
377
  */
397
- productCardRender?: (product: Product) => React.ReactNode
378
+ productCardRender?: (product: any, productHandle: string) => React.ReactNode
398
379
  }
399
380
 
400
381
  export interface UseChatStateReturn {
@@ -554,10 +535,10 @@ export function useChatState(options: UseChatStateOptions = {}): UseChatStateRet
554
535
  // 标记当前消息是否已触发 onTextMessage 回调(避免重复触发)
555
536
  const textMessageCallbackTriggeredRef = useRef<boolean>(false)
556
537
 
557
- // 产品映射缓存 (shopifyId → Product),用于实时解析占位符
538
+ // 产品映射缓存 (handle → Product),用于实时解析占位符
558
539
  const productMapRef = useRef<Map<string, Product>>(new Map())
559
540
 
560
- // 原始产品数据缓存 (shopifyId → raw backend product),用于 productCardRender
541
+ // 原始产品数据缓存 (handle → raw backend product),用于 productCardRender
561
542
  const rawProductMapRef = useRef<Map<string, any>>(new Map())
562
543
 
563
544
  // 文本缓冲区,用于存储未完成的文本(处理占位符跨越多个 delta 的情况)
@@ -798,40 +779,25 @@ export function useChatState(options: UseChatStateOptions = {}): UseChatStateRet
798
779
  onProductList?.()
799
780
 
800
781
  // 缓存原始后端产品数据(用于 productCardRender)
782
+ // 使用 handle 作为 key 进行匹配
801
783
  contentData.forEach((rawProduct: any) => {
802
- if (rawProduct && rawProduct.shopify_product_id) {
803
- const shopifyId = rawProduct.shopify_product_id
804
- // 1. 使用完整的 shopifyId 作为key
805
- rawProductMapRef.current.set(shopifyId, rawProduct)
806
-
807
- // 2. 同时提取数字部分作为key
808
- const numericId = shopifyId.match(/\d+$/)?.[0]
809
- if (numericId) {
810
- rawProductMapRef.current.set(numericId, rawProduct)
811
- }
784
+ if (rawProduct && rawProduct.handle) {
785
+ rawProductMapRef.current.set(rawProduct.handle, rawProduct)
786
+ console.log('[useChatState] 缓存原始产品数据, handle:', rawProduct.handle)
812
787
  }
813
788
  })
814
789
 
815
790
  // 使用统一的产品转换工具函数
816
791
  const transformedProducts = transformProducts(contentData, site)
817
792
 
818
- // 建立产品映射缓存 (shopifyId → Product)
819
- // 用于后续在 message_end 时解析文本中的 {{shopifyId}}
793
+ // 建立产品映射缓存 (handle → Product)
794
+ // 用于后续在 message_end 时解析文本中的 {{handle}}
820
795
  transformedProducts.forEach(product => {
821
- if (product && product.shopifyId) {
822
- // 1. 使用完整的 shopifyId 作为key(如 "gid://shopify/Product/123")
823
- productMapRef.current.set(product.shopifyId, product)
824
-
825
- // 2. 同时提取数字部分作为key(如 "123"),支持简写格式
826
- // 从 "gid://shopify/Product/123" 或 "123" 中提取纯数字
827
- const numericId = product.shopifyId.match(/\d+$/)?.[0]
828
- if (numericId) {
829
- productMapRef.current.set(numericId, product)
830
- }
796
+ if (product && product.handle) {
797
+ productMapRef.current.set(product.handle, product)
831
798
 
832
799
  console.log('[useChatState] 建立产品映射:', {
833
- fullId: product.shopifyId,
834
- numericId,
800
+ handle: product.handle,
835
801
  title: product.title,
836
802
  })
837
803
  }
@@ -86,10 +86,11 @@ export interface TextContent {
86
86
  export interface ProductCardContent {
87
87
  type: 'product_card'
88
88
  data: {
89
- product: Product
89
+ product?: Product
90
90
  rawProduct?: any // Raw backend product data (for custom render)
91
+ productHandle: string // Product ID from placeholder {{product:ID}}, for app-level product lookup
91
92
  onAddToCart?: (product: Product) => void
92
- productCardRender?: (product: any) => React.ReactNode
93
+ productCardRender?: (product: any, productHandle: string) => React.ReactNode
93
94
  }
94
95
  }
95
96
 
@@ -820,7 +821,6 @@ export interface LiveChatWidgetProps {
820
821
 
821
822
  /**
822
823
  * 欢迎消息
823
- * @default "你好!我是 AI 助手,有什么可以帮助你的吗?"
824
824
  */
825
825
  welcomeMessage?: string
826
826
 
@@ -952,21 +952,28 @@ export interface LiveChatWidgetProps {
952
952
  * 自定义产品卡片渲染函数
953
953
  * 用于自定义渲染 product_card 类型的产品卡片
954
954
  * 当提供此函数时,将替代默认的产品卡片渲染逻辑
955
- * @param product 原始后端产品数据(未经转换的数据)
955
+ * @param product 原始后端产品数据(未经转换的数据),如果在 product_list 中找不到则为 undefined
956
+ * @param productHandle 文本占位符中的产品 ID(如 {{product:ID}} 中的 ID),可用于应用层查询产品数据
956
957
  * @returns React 可渲染的内容
957
958
  * @example
958
959
  * ```tsx
959
960
  * <LiveChatWidget
960
- * productCardRender={(product) => (
961
- * <div>
962
- * <h3>{product.title}</h3>
963
- * <p>{product.price_range?.min}</p>
964
- * </div>
965
- * )}
961
+ * productCardRender={(product, productHandle) => {
962
+ * // product 可能为 undefined,此时可用 productHandle 查询产品
963
+ * if (!product) {
964
+ * return <ProductCardByHandle handle={productHandle} />
965
+ * }
966
+ * return (
967
+ * <div>
968
+ * <h3>{product.title}</h3>
969
+ * <p>{product.price_range?.min}</p>
970
+ * </div>
971
+ * )
972
+ * }}
966
973
  * />
967
974
  * ```
968
975
  */
969
- productCardRender?: (product: any) => React.ReactNode
976
+ productCardRender?: (product: any, productHandle: string) => React.ReactNode
970
977
 
971
978
  /**
972
979
  * 输入框底部提示文本
@@ -11,7 +11,8 @@ export {
11
11
 
12
12
  export * from './credits/index.js'
13
13
 
14
- export * from './registration/index'
14
+ export * from './registration/index.js'
15
+
15
16
 
16
17
 
17
18
  // LiveChatWidget 导出