ibc-ai-web-sdk 2.0.0
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 +607 -0
- package/dist/index.cjs.js +6256 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.esm.js +6245 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.umd.js +6262 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/index.umd.min.js +1 -0
- package/index.d.ts +96 -0
- package/miniprogram/README.md +220 -0
- package/miniprogram/ai-chat-dialog/ai-chat-dialog.js +433 -0
- package/miniprogram/ai-chat-dialog/ai-chat-dialog.json +4 -0
- package/miniprogram/ai-chat-dialog/ai-chat-dialog.wxml +82 -0
- package/miniprogram/ai-chat-dialog/ai-chat-dialog.wxss +88 -0
- package/miniprogram/config/defaultConfig.js +40 -0
- package/miniprogram/core/AIChatClient.js +326 -0
- package/miniprogram/types.ts +178 -0
- package/miniprogram/utils/errorCodes.js +25 -0
- package/miniprogram/utils/logger.js +51 -0
- package/miniprogram/utils/markdownParser.js +97 -0
- package/miniprogram/utils/messageIdGenerator.js +23 -0
- package/package.json +68 -0
- package/src/types.ts +599 -0
package/README.md
ADDED
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
# IBC AI Web SDK v2.0
|
|
2
|
+
|
|
3
|
+
> **纯JavaScript实现的AI对话组件**,支持任意前端框架:Vue、React、Angular、原生HTML等
|
|
4
|
+
|
|
5
|
+
## ✨ 特性
|
|
6
|
+
|
|
7
|
+
- 🚫 **零框架依赖** - 纯JavaScript实现,基于Web Components (Custom Elements + Shadow DOM)
|
|
8
|
+
- 🔌 **框架无关** - 可在Vue/React/Angular/Svelte/原生HTML中无缝使用
|
|
9
|
+
- 🎨 **主题可定制** - 支持亮色/暗色主题,CSS变量自定义
|
|
10
|
+
- 💬 **流式响应** - 支持SSE流式输出,实时显示AI回复
|
|
11
|
+
- 📱 **响应式设计** - 适配桌面端和移动端
|
|
12
|
+
- ♿ **无障碍访问** - 遵循ARIA规范,支持键盘操作
|
|
13
|
+
- 🎯 **轻量级** - Gzip后 < 15KB
|
|
14
|
+
|
|
15
|
+
## 📦 安装
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install ibc-ai-web-sdk
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
或直接引入CDN:
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<script src="https://unpkg.com/ibc-ai-web-sdk@latest/dist/index.umd.min.js"></script>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 🚀 快速开始
|
|
28
|
+
|
|
29
|
+
### 方式一:原生HTML使用(最简单)
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<!DOCTYPE html>
|
|
33
|
+
<html>
|
|
34
|
+
<head>
|
|
35
|
+
<title>AI Chat Demo</title>
|
|
36
|
+
</head>
|
|
37
|
+
<body>
|
|
38
|
+
<!-- 触发按钮 -->
|
|
39
|
+
<button onclick="openChat()">打开AI助手</button>
|
|
40
|
+
|
|
41
|
+
<script type="module">
|
|
42
|
+
import { createAIChatDialog } from './node_modules/ibc-ai-web-sdk/dist/index.esm.js';
|
|
43
|
+
|
|
44
|
+
// 或CDN方式:
|
|
45
|
+
// const dialog = AICreateChatDialog({...});
|
|
46
|
+
|
|
47
|
+
let chatInstance;
|
|
48
|
+
|
|
49
|
+
function openChat() {
|
|
50
|
+
if (!chatInstance) {
|
|
51
|
+
chatInstance = createAIChatDialog({
|
|
52
|
+
apiBaseUrl: 'https://your-api.com/ai',
|
|
53
|
+
authToken: 'your-token',
|
|
54
|
+
title: '智能客服',
|
|
55
|
+
placeholder: '请输入您的问题...',
|
|
56
|
+
theme: 'light'
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
chatInstance.open();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 暴露到全局供onclick调用
|
|
64
|
+
window.openChat = openChat;
|
|
65
|
+
</script>
|
|
66
|
+
</body>
|
|
67
|
+
</html>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 方式二:Vue项目使用
|
|
71
|
+
|
|
72
|
+
#### 选项式API(Options API)
|
|
73
|
+
|
|
74
|
+
```vue
|
|
75
|
+
<template>
|
|
76
|
+
<div>
|
|
77
|
+
<button @click="openChat">打开AI助手</button>
|
|
78
|
+
|
|
79
|
+
<!-- 使用组件包装器 -->
|
|
80
|
+
<AiChatWrapper
|
|
81
|
+
:visible.sync="showChat"
|
|
82
|
+
:config="chatConfig"
|
|
83
|
+
@message-send="onMessageSend"
|
|
84
|
+
@message-received="onMessageReceived"
|
|
85
|
+
@close="showChat = false"
|
|
86
|
+
/>
|
|
87
|
+
</div>
|
|
88
|
+
</template>
|
|
89
|
+
|
|
90
|
+
<script>
|
|
91
|
+
import { installVuePlugin, AIChatDialog } from 'ibc-ai-web-sdk';
|
|
92
|
+
|
|
93
|
+
export default {
|
|
94
|
+
data() {
|
|
95
|
+
return {
|
|
96
|
+
showChat: false,
|
|
97
|
+
chatConfig: {
|
|
98
|
+
apiBaseUrl: '/api/ai',
|
|
99
|
+
authToken: '',
|
|
100
|
+
title: 'AI 助手',
|
|
101
|
+
welcomeMessage: '你好!我是AI助手,有什么可以帮助您的吗?'
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
mounted() {
|
|
107
|
+
// 注册Vue插件
|
|
108
|
+
installVuePlugin(this.$root.constructor); // Vue 2
|
|
109
|
+
// 或在 main.js 中全局注册:
|
|
110
|
+
// import { installVuePlugin } from 'ibc-ai-web-sdk';
|
|
111
|
+
// Vue.use(installVuePlugin);
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
methods: {
|
|
115
|
+
openChat() {
|
|
116
|
+
this.showChat = true;
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
onMessageSend(message) {
|
|
120
|
+
console.log('用户发送:', message.content);
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
onMessageReceived(message) {
|
|
124
|
+
console.log('AI回复:', message.content);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
</script>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### 组合式API(Composition API)+ 直接使用Web Component
|
|
132
|
+
|
|
133
|
+
```vue
|
|
134
|
+
<template>
|
|
135
|
+
<div>
|
|
136
|
+
<button @click="handleOpen">打开AI助手</button>
|
|
137
|
+
</div>
|
|
138
|
+
</template>
|
|
139
|
+
|
|
140
|
+
<script setup>
|
|
141
|
+
import { ref, onMounted, onUnmounted } from 'vue';
|
|
142
|
+
import { createAIChatDialog } from 'ibc-ai-web-sdk';
|
|
143
|
+
|
|
144
|
+
const chatRef = ref(null);
|
|
145
|
+
|
|
146
|
+
onMounted(() => {
|
|
147
|
+
chatRef.value = createAIChatDialog({
|
|
148
|
+
apiBaseUrl: 'https://api.example.com/ai',
|
|
149
|
+
title: '智能助手',
|
|
150
|
+
theme: 'dark',
|
|
151
|
+
width: 500,
|
|
152
|
+
height: 650,
|
|
153
|
+
|
|
154
|
+
// 回调事件
|
|
155
|
+
onMessageSend: (msg) => console.log('发送:', msg),
|
|
156
|
+
onMessageReceived: (msg) => console.log('收到:', msg),
|
|
157
|
+
onError: (err) => console.error('错误:', err)
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const handleOpen = () => {
|
|
162
|
+
chatRef.value?.open();
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
onUnmounted(() => {
|
|
166
|
+
chatRef.value?.destroy();
|
|
167
|
+
});
|
|
168
|
+
</script>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### 方式三:React项目使用
|
|
172
|
+
|
|
173
|
+
#### 使用Hook(推荐)
|
|
174
|
+
|
|
175
|
+
```jsx
|
|
176
|
+
import React from 'react';
|
|
177
|
+
import { useAIChat } from 'ibc-ai-web-sdk';
|
|
178
|
+
|
|
179
|
+
function App() {
|
|
180
|
+
const { open, close, messages, isLoading } = useAIChat({
|
|
181
|
+
apiBaseUrl: process.env.REACT_APP_AI_API_URL,
|
|
182
|
+
authToken: localStorage.getItem('token'),
|
|
183
|
+
title: 'AI 智能助手',
|
|
184
|
+
placeholder: '输入您的问题...',
|
|
185
|
+
theme: 'light',
|
|
186
|
+
|
|
187
|
+
// 回调
|
|
188
|
+
onMessageSend: (message) => {
|
|
189
|
+
console.log('用户发送:', message);
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
onMessageReceived: ({ content }) => {
|
|
193
|
+
console.log('AI回复:', content);
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
onError: (error) => {
|
|
197
|
+
console.error('发生错误:', error);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
return (
|
|
202
|
+
<div className="app">
|
|
203
|
+
<h1>My App</h1>
|
|
204
|
+
|
|
205
|
+
<button onClick={open}>
|
|
206
|
+
{isLoading ? '对话中...' : '打开AI助手'}
|
|
207
|
+
</button>
|
|
208
|
+
|
|
209
|
+
{/* 显示消息历史 */}
|
|
210
|
+
<div className="message-history">
|
|
211
|
+
{messages.map((msg) => (
|
|
212
|
+
<div key={msg.id} className={`message ${msg.role}`}>
|
|
213
|
+
<strong>{msg.role === 'user' ? '我' : 'AI'}:</strong>
|
|
214
|
+
{msg.content}
|
|
215
|
+
</div>
|
|
216
|
+
))}
|
|
217
|
+
</div>
|
|
218
|
+
|
|
219
|
+
<button onClick={close}>关闭</button>
|
|
220
|
+
</div>
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export default App;
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### 类组件方式
|
|
228
|
+
|
|
229
|
+
```jsx
|
|
230
|
+
import React, { Component } from 'react';
|
|
231
|
+
import { createAIChatDialog } from 'ibc-ai-web-sdk';
|
|
232
|
+
|
|
233
|
+
class ChatButton extends Component {
|
|
234
|
+
constructor(props) {
|
|
235
|
+
super(props);
|
|
236
|
+
this.chatRef = null;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
componentDidMount() {
|
|
240
|
+
this.chatRef = createAIChatDialog({
|
|
241
|
+
apiBaseUrl: '/api/ai',
|
|
242
|
+
title: 'AI 助手',
|
|
243
|
+
|
|
244
|
+
onMessageSend: (msg) => {
|
|
245
|
+
console.log('发送:', msg);
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
onMessageReceived: (data) => {
|
|
249
|
+
console.log('收到:', data);
|
|
250
|
+
this.props.onReceive?.(data);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
componentWillUnmount() {
|
|
256
|
+
if (this.chatRef) {
|
|
257
|
+
this.chatRef.destroy();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
handleClick = () => {
|
|
262
|
+
if (this.chatRef) {
|
|
263
|
+
this.chatRef.open();
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
render() {
|
|
268
|
+
return (
|
|
269
|
+
<button onClick={this.handleClick}>
|
|
270
|
+
打开AI助手
|
|
271
|
+
</button>
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export default ChatButton;
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### 方式四:Angular项目使用
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
// ai-chat.service.ts
|
|
283
|
+
import { Injectable, OnDestroy } from '@angular/core';
|
|
284
|
+
import { createAIChatDialog, AIChatDialog } from 'ibc-ai-web-sdk';
|
|
285
|
+
|
|
286
|
+
@Injectable({
|
|
287
|
+
providedIn: 'root'
|
|
288
|
+
})
|
|
289
|
+
export class AiChatService implements OnDestroy {
|
|
290
|
+
private dialog: AIChatDialog | null = null;
|
|
291
|
+
|
|
292
|
+
constructor() {}
|
|
293
|
+
|
|
294
|
+
init(config?: any): void {
|
|
295
|
+
if (!this.dialog) {
|
|
296
|
+
this.dialog = createAIChatDialog({
|
|
297
|
+
apiBaseUrl: environment.aiApiUrl,
|
|
298
|
+
...config
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
open(): void {
|
|
304
|
+
this.init(); // 确保已初始化
|
|
305
|
+
this.dialog?.open();
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
close(): void {
|
|
309
|
+
this.dialog?.close();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
sendMessage(content: string): void {
|
|
313
|
+
if (this.dialog) {
|
|
314
|
+
// 通过DOM操作设置消息并发送
|
|
315
|
+
const textarea = this.dialog.shadowRoot?.querySelector('.ai-textarea');
|
|
316
|
+
if (textarea) {
|
|
317
|
+
// 使用内部方法发送
|
|
318
|
+
(this.dialog as any).addMessage({ role: 'user', content });
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
ngOnDestroy(): void {
|
|
324
|
+
this.dialog?.destroy();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
// app.component.ts
|
|
331
|
+
import { Component } from '@angular/core';
|
|
332
|
+
import { AiChatService } from './ai-chat.service';
|
|
333
|
+
|
|
334
|
+
@Component({
|
|
335
|
+
selector: 'app-root',
|
|
336
|
+
template: `
|
|
337
|
+
<button (click)="openChat()">打开AI助手</button>
|
|
338
|
+
`
|
|
339
|
+
})
|
|
340
|
+
export class AppComponent {
|
|
341
|
+
constructor(private aiChat: AiChatService) {}
|
|
342
|
+
|
|
343
|
+
openChat(): void {
|
|
344
|
+
this.aiChat.open();
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### 方式五:Svelte使用
|
|
350
|
+
|
|
351
|
+
```svelte
|
|
352
|
+
<script>
|
|
353
|
+
import { onMount, onDestroy } from 'svelte';
|
|
354
|
+
import { createAIChatDialog } from 'ibc-ai-web-sdk';
|
|
355
|
+
|
|
356
|
+
let chat;
|
|
357
|
+
|
|
358
|
+
onMount(() => {
|
|
359
|
+
chat = createAIChatDialog({
|
|
360
|
+
apiBaseUrl: '/api/ai',
|
|
361
|
+
title: 'Svelte AI Chat',
|
|
362
|
+
|
|
363
|
+
onMessageSend: (msg) => {
|
|
364
|
+
console.log('发送:', msg);
|
|
365
|
+
},
|
|
366
|
+
|
|
367
|
+
onMessageReceived: (data) => {
|
|
368
|
+
console.log('收到:', data);
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
onDestroy(() => {
|
|
374
|
+
chat?.destroy();
|
|
375
|
+
});
|
|
376
|
+
</script>
|
|
377
|
+
|
|
378
|
+
<button on:click={() => chat?.open()}>
|
|
379
|
+
打开AI助手
|
|
380
|
+
</button>
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## ⚙️ 配置选项
|
|
384
|
+
|
|
385
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
386
|
+
|------|------|--------|------|
|
|
387
|
+
| `apiBaseUrl` | `string` | `'/api/ai'` | API基础URL |
|
|
388
|
+
| `authToken` | `string` | `''` | 认证Token |
|
|
389
|
+
| `defaultParams` | `Object` | `{}` | 默认请求参数 |
|
|
390
|
+
| `placeholder` | `string` | `'请输入您的问题...'` | 输入框占位符 |
|
|
391
|
+
| `title` | `string` | `'AI 智能助手'` | 对话框标题 |
|
|
392
|
+
| `width` | `number` | `420` | 对话框宽度(px) |
|
|
393
|
+
| `height` | `number` | `600` | 对话框高度(px) |
|
|
394
|
+
| `theme` | `string` | `'light'` | 主题:`light` / `dark` |
|
|
395
|
+
| `showDragHandle` | `boolean` | `true` | 是否允许拖拽头部移动位置 |
|
|
396
|
+
| `enableHistory` | `boolean` | `true` | 是否启用消息历史记录 |
|
|
397
|
+
| `maxHistoryLength` | `number` | `50` | 最大历史消息数量 |
|
|
398
|
+
| `welcomeMessage` | `string` | - | 欢迎语(空状态时显示) |
|
|
399
|
+
| `errorMessage` | `string` | - | 错误提示文案 |
|
|
400
|
+
| `networkErrorMessage` | `string` | - | 网络错误提示文案 |
|
|
401
|
+
| `emptyMessageError` | `string` | - | 空消息错误提示文案 |
|
|
402
|
+
| `streamingEnabled` | `boolean` | `true` | 是否启用流式响应(SSE) |
|
|
403
|
+
| `requestTimeout` | `number` | `30000` | 请求超时时间(ms) |
|
|
404
|
+
| `customStyles` | `Object` | `null` | 自定义CSS变量 |
|
|
405
|
+
|
|
406
|
+
### 回调函数
|
|
407
|
+
|
|
408
|
+
| 回调 | 参数 | 说明 |
|
|
409
|
+
|------|------|------|
|
|
410
|
+
| `onMessageSend` | `(message: Object)` | 用户发送消息时触发 |
|
|
411
|
+
| `onMessageReceived` | `(data: {content, done})` | 收到AI回复时触发(流式模式下多次触发) |
|
|
412
|
+
| `onError` | `(error: Error)` | 发生错误时触发 |
|
|
413
|
+
| `onOpen` | - | 对话框打开时触发 |
|
|
414
|
+
| `onClose` | - | 对话框关闭时触发 |
|
|
415
|
+
|
|
416
|
+
## 🎨 主题定制
|
|
417
|
+
|
|
418
|
+
### CSS变量覆盖
|
|
419
|
+
|
|
420
|
+
```javascript
|
|
421
|
+
createAIChatDialog({
|
|
422
|
+
customStyles: {
|
|
423
|
+
'primary-color': '#8b5cf6', // 主色调改为紫色
|
|
424
|
+
'primary-hover': '#7c3aed', // 主色悬停态
|
|
425
|
+
'bg-color': '#faf5ff', // 背景色
|
|
426
|
+
'text-color': '#1f2937', // 文字颜色
|
|
427
|
+
'border-radius': '16px' // 圆角大小
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### 完整CSS变量列表
|
|
433
|
+
|
|
434
|
+
```css
|
|
435
|
+
:host {
|
|
436
|
+
--ai-primary-color: #2563eb; /* 主色调 */
|
|
437
|
+
--ai-primary-hover: #1d4ed8; /* 主色悬停态 */
|
|
438
|
+
--ai-bg-color: #ffffff; /* 背景色 */
|
|
439
|
+
--ai-text-color: #1f2937; /* 文字颜色 */
|
|
440
|
+
--ai-text-secondary: #6b7280; /* 次要文字颜色 */
|
|
441
|
+
--ai-border-color: #e5e7eb; /* 边框颜色 */
|
|
442
|
+
--ai-user-bg: gradient(...); /* 用户消息背景 */
|
|
443
|
+
--ai-assistant-bg: #f3f4f6; /* 助手消息背景 */
|
|
444
|
+
--ai-input-bg: #f9fafb; /* 输入框背景 */
|
|
445
|
+
--ai-shadow: shadow(...); /* 阴影效果 */
|
|
446
|
+
--ai-overlay: rgba(0,0,0,0.5); /* 遮罩层颜色 */
|
|
447
|
+
--ai-border-radius: 12px; /* 圆角大小 */
|
|
448
|
+
--ai-header-height: 56px; /* 头部高度 */
|
|
449
|
+
}
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
## 📡 API方法
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
// 创建实例
|
|
456
|
+
const dialog = createAIChatDialog(config);
|
|
457
|
+
|
|
458
|
+
// 控制显示
|
|
459
|
+
dialog.open(); // 打开对话框
|
|
460
|
+
dialog.close(); // 关闭对话框
|
|
461
|
+
dialog.toggle(forceState?); // 切换状态
|
|
462
|
+
|
|
463
|
+
// 消息操作
|
|
464
|
+
dialog.addMessage(message); // 手动添加消息
|
|
465
|
+
dialog.clearMessages(); // 清空消息历史
|
|
466
|
+
dialog.sendMessage(text); // 发送消息(程序化调用)
|
|
467
|
+
|
|
468
|
+
// 状态控制
|
|
469
|
+
dialog.setLoading(boolean); // 设置加载状态
|
|
470
|
+
dialog.updateConfig(newConfig); // 更新配置
|
|
471
|
+
|
|
472
|
+
// 生命周期
|
|
473
|
+
dialog.destroy(); // 销毁实例并清理DOM
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
## 🎯 事件监听
|
|
477
|
+
|
|
478
|
+
```javascript
|
|
479
|
+
const dialog = createAIChatDialog();
|
|
480
|
+
|
|
481
|
+
// 使用addEventListener
|
|
482
|
+
dialog.addEventListener('open', () => console.log('打开'));
|
|
483
|
+
dialog.addEventListener('close', () => console.log('关闭'));
|
|
484
|
+
dialog.addEventListener('message-send', (e) => {
|
|
485
|
+
console.log('发送的消息:', e.detail);
|
|
486
|
+
});
|
|
487
|
+
dialog.addEventListener('message-received', (e) => {
|
|
488
|
+
console.log('收到的回复:', e.detail);
|
|
489
|
+
});
|
|
490
|
+
dialog.addEventListener('error', (e) => {
|
|
491
|
+
console.error('错误:', e.detail);
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
// 或在配置中使用回调
|
|
495
|
+
createAIChatDialog({
|
|
496
|
+
onOpen: () => {},
|
|
497
|
+
onClose: () => {},
|
|
498
|
+
onMessageSend: (msg) => {},
|
|
499
|
+
onMessageReceived: (data) => {},
|
|
500
|
+
onError: (err) => {}
|
|
501
|
+
});
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
## 🔌 服务端API要求
|
|
505
|
+
|
|
506
|
+
SDK默认期望以下API接口:
|
|
507
|
+
|
|
508
|
+
### POST `/api/ai/chat`
|
|
509
|
+
|
|
510
|
+
**请求体:**
|
|
511
|
+
```json
|
|
512
|
+
{
|
|
513
|
+
"message": "你好",
|
|
514
|
+
"history": [
|
|
515
|
+
{ "role": "user", "content": "上一条问题" },
|
|
516
|
+
{ "role": "assistant", "content": "上一条回答" }
|
|
517
|
+
]
|
|
518
|
+
}
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
**普通响应:**
|
|
522
|
+
```json
|
|
523
|
+
{
|
|
524
|
+
"content": "您好!我是AI助手...",
|
|
525
|
+
"id": "msg_xxx"
|
|
526
|
+
}
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
**流式响应 (SSE):**
|
|
530
|
+
```
|
|
531
|
+
data: {"content": "您好"}
|
|
532
|
+
data: {"content": "!"}
|
|
533
|
+
data: {"delta": "我是"}
|
|
534
|
+
...
|
|
535
|
+
data: [DONE]
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
**认证:**
|
|
539
|
+
- Header: `Authorization: Bearer <token>`
|
|
540
|
+
- 或通过配置 `authToken` 参数自动添加
|
|
541
|
+
|
|
542
|
+
## 🏗️ 构建与开发
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
# 安装依赖
|
|
546
|
+
npm install
|
|
547
|
+
|
|
548
|
+
# 开发模式(监听文件变化)
|
|
549
|
+
npm run dev
|
|
550
|
+
|
|
551
|
+
# 构建
|
|
552
|
+
npm run build
|
|
553
|
+
|
|
554
|
+
# 生产构建(压缩+去除调试代码)
|
|
555
|
+
npm run build:prod
|
|
556
|
+
|
|
557
|
+
# 代码检查
|
|
558
|
+
npm run lint
|
|
559
|
+
|
|
560
|
+
# 测试
|
|
561
|
+
npm test
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
## 📦 输出格式
|
|
565
|
+
|
|
566
|
+
构建后会生成以下文件:
|
|
567
|
+
|
|
568
|
+
| 文件 | 格式 | 用途 |
|
|
569
|
+
|------|------|------|
|
|
570
|
+
| `dist/index.esm.js` | ES Module | modern打包工具(Vite/Webpack/Rollup) |
|
|
571
|
+
| `dist/index.cjs.js` | CommonJS | Node.js/老版本打包工具 |
|
|
572
|
+
| `dist/index.umd.js` | UMD | 浏览器直接引用(未压缩) |
|
|
573
|
+
| `dist/index.umd.min.js` | UMD Minified | 浏览器直接引用(生产环境) |
|
|
574
|
+
|
|
575
|
+
## 🔄 从v1.x迁移
|
|
576
|
+
|
|
577
|
+
如果你之前使用的是Vue版本的v1.x:
|
|
578
|
+
|
|
579
|
+
```javascript
|
|
580
|
+
// v1.x (Vue组件)
|
|
581
|
+
import AIChatDialog from 'ibc-ai-web-sdk';
|
|
582
|
+
// <AIChatDialog :visible.sync="visible" :config="config" />
|
|
583
|
+
|
|
584
|
+
// v2.x (纯JS + Web Components)
|
|
585
|
+
import { createAIChatDialog } from 'ibc-ai-web-sdk';
|
|
586
|
+
|
|
587
|
+
const dialog = createAIChatDialog({
|
|
588
|
+
apiBaseUrl: '/api/ai',
|
|
589
|
+
// ... 其他配置不变
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
dialog.open();
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
主要变化:
|
|
596
|
+
1. **移除Vue依赖** - 不再需要Vue运行时
|
|
597
|
+
2. **API更简洁** - `createAIChatDialog()` 返回实例对象
|
|
598
|
+
3. **完全隔离** - Shadow DOM确保样式不会污染宿主页面
|
|
599
|
+
4. **更多框架支持** - 原生支持React Hook、Angular Service等
|
|
600
|
+
|
|
601
|
+
## 🤝 贡献
|
|
602
|
+
|
|
603
|
+
欢迎提交Issue和Pull Request!
|
|
604
|
+
|
|
605
|
+
## 📄 License
|
|
606
|
+
|
|
607
|
+
MIT License
|