@blueking/ai-blueking 0.5.0-beta.7 → 0.5.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 +292 -562
- package/dist/vue2/index.es.min.js +2336 -2456
- package/dist/vue2/index.iife.min.js +55 -55
- package/dist/vue2/index.umd.min.js +32 -32
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,644 +1,374 @@
|
|
|
1
|
-
# AI
|
|
1
|
+
# AI 小鲸 (AI Blueking) 使用文档
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 简介
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- [安装](#安装)
|
|
7
|
-
- [特性](#特性)
|
|
8
|
-
- [使用指南](#使用指南)
|
|
9
|
-
- [开发调试](#开发调试)
|
|
5
|
+
AI 小鲸是一个智能对话组件,支持 Vue2/Vue3 框架,提供丰富的交互功能和灵活的配置选项。只需简单配置,即可快速接入智能对话能力,提升应用的用户体验。
|
|
10
6
|
|
|
11
|
-
##
|
|
7
|
+
## 特性
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
- **实时对话**:支持流式输出,让对话更自然流畅
|
|
10
|
+
- **内容引用**:选中文本即可快速引用并提问
|
|
11
|
+
- **快捷操作**:支持预设常用功能和提示词
|
|
12
|
+
- **可拖拽界面**:自由调整窗口位置和大小
|
|
13
|
+
- **开箱即用**:传入 Agent 地址即可快速接入业务
|
|
14
|
+
- **跨框架支持**:同时支持 Vue2 和 Vue3 框架
|
|
14
15
|
|
|
15
16
|
## 安装
|
|
16
17
|
|
|
17
18
|
```bash
|
|
18
|
-
npm
|
|
19
|
+
npm install @blueking/ai-blueking
|
|
19
20
|
```
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- 支持 popup 弹框唤起
|
|
24
|
-
- 支持引用提问功能
|
|
25
|
-
- 支持快捷提问(当前支持翻译、解释功能)
|
|
26
|
-
- 支持使用 `enablePopup` 属性控制弹框唤起(默认为 true)
|
|
27
|
-
|
|
28
|
-
## 使用指南
|
|
22
|
+
或
|
|
29
23
|
|
|
30
|
-
|
|
24
|
+
```bash
|
|
25
|
+
yarn add @blueking/ai-blueking
|
|
26
|
+
```
|
|
31
27
|
|
|
32
|
-
|
|
28
|
+
## 基本使用
|
|
33
29
|
|
|
34
|
-
|
|
30
|
+
### Vue 3
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
```vue
|
|
33
|
+
<template>
|
|
34
|
+
<div>
|
|
35
|
+
<button @click="showAI">打开 AI 小鲸</button>
|
|
36
|
+
|
|
37
|
+
<AIBlueking
|
|
38
|
+
ref="aiBlueking"
|
|
39
|
+
:url="apiUrl"
|
|
40
|
+
@show="handleShow"
|
|
41
|
+
@close="handleClose"
|
|
42
|
+
/>
|
|
43
|
+
</div>
|
|
44
|
+
</template>
|
|
38
45
|
|
|
39
|
-
|
|
46
|
+
<script lang="ts" setup>
|
|
47
|
+
import { ref } from 'vue';
|
|
48
|
+
import AIBlueking from '@blueking/ai-blueking';
|
|
49
|
+
import '@blueking/ai-blueking/dist/vue3/style.css';
|
|
40
50
|
|
|
41
|
-
|
|
51
|
+
const aiBlueking = ref(null);
|
|
52
|
+
const apiUrl = 'https://your-api-endpoint.com/assistant/';
|
|
42
53
|
|
|
43
|
-
|
|
54
|
+
const showAI = () => {
|
|
55
|
+
console.log('AI 小鲸已显示');
|
|
56
|
+
};
|
|
44
57
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
prompt?: string; // 使用的 prompt 模板(可选)
|
|
50
|
-
}
|
|
58
|
+
const handleClose = () => {
|
|
59
|
+
console.log('AI 小鲸已关闭');
|
|
60
|
+
};
|
|
61
|
+
</script>
|
|
51
62
|
```
|
|
52
63
|
|
|
53
|
-
|
|
64
|
+
### Vue 2
|
|
54
65
|
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
```vue
|
|
67
|
+
<template>
|
|
68
|
+
<div>
|
|
69
|
+
<button @click="showAI">打开 AI 小鲸</button>
|
|
70
|
+
|
|
71
|
+
<AIBlueking
|
|
72
|
+
ref="aiBlueking"
|
|
73
|
+
:url="apiUrl"
|
|
74
|
+
@show="handleShow"
|
|
75
|
+
@close="handleClose"
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
</template>
|
|
66
79
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
<script>
|
|
81
|
+
import AIBlueking from '@blueking/ai-blueking/vue2';
|
|
82
|
+
import '@blueking/ai-blueking/dist/vue2/style.css';
|
|
83
|
+
|
|
84
|
+
export default {
|
|
85
|
+
components: {
|
|
86
|
+
AIBlueking
|
|
87
|
+
},
|
|
88
|
+
data() {
|
|
89
|
+
return {
|
|
90
|
+
apiUrl: 'https://your-api-endpoint.com/assistant/'
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
methods: {
|
|
94
|
+
showAI() {
|
|
95
|
+
this.$refs.aiBlueking.handleShow();
|
|
96
|
+
},
|
|
97
|
+
handleShow() {
|
|
98
|
+
console.log('AI 小鲸已显示');
|
|
82
99
|
},
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
handleClose() {
|
|
101
|
+
console.log('AI 小鲸已关闭');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
85
104
|
};
|
|
105
|
+
</script>
|
|
86
106
|
```
|
|
87
107
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
108
|
+
## 属性 (Props)
|
|
109
|
+
|
|
110
|
+
| 属性名 | 类型 | 默认值 | 描述 |
|
|
111
|
+
|--------|------|--------|------|
|
|
112
|
+
| url | String | '' | AI 服务接口地址,必须设置 |
|
|
113
|
+
| enablePopup | Boolean | true | 是否启用选中文本后的弹出操作窗口 |
|
|
114
|
+
| shortcuts | Array | [...] | 快捷操作列表 |
|
|
115
|
+
| prompts | Array | [] | 预设提示词列表 |
|
|
116
|
+
|
|
117
|
+
### shortcuts 格式示例
|
|
118
|
+
|
|
119
|
+
```javascript
|
|
120
|
+
[
|
|
121
|
+
{
|
|
122
|
+
label: '解释',
|
|
123
|
+
key: 'explanation',
|
|
124
|
+
prompt: '解释一下内容: {{ SELECTED_TEXT }}',
|
|
125
|
+
icon: 'icon-explanation'
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
label: '翻译',
|
|
129
|
+
key: 'translate',
|
|
130
|
+
prompt: '翻译一下内容: {{ SELECTED_TEXT }}',
|
|
131
|
+
icon: 'icon-translate'
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
```
|
|
91
135
|
|
|
92
|
-
|
|
136
|
+
### prompts 格式示例
|
|
93
137
|
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
</span>
|
|
101
|
-
<a href="xxx" target="_blank" class="knowledge-link">
|
|
102
|
-
1. vivo 容器平台如何实现资源超卖方案
|
|
103
|
-
<i class="ai-blueking-icon ai-blueking-cc-jump-link"></i>
|
|
104
|
-
</a>
|
|
105
|
-
</section>
|
|
138
|
+
```javascript
|
|
139
|
+
[
|
|
140
|
+
'请概括这段内容的主要观点',
|
|
141
|
+
'请帮我分析这段文字中的问题',
|
|
142
|
+
'请用简单的语言解释这个概念'
|
|
143
|
+
]
|
|
106
144
|
```
|
|
107
145
|
|
|
108
|
-
|
|
146
|
+
## 事件 (Events)
|
|
109
147
|
|
|
110
|
-
|
|
148
|
+
| 事件名 | 参数 | 描述 |
|
|
149
|
+
|--------|------|------|
|
|
150
|
+
| show | - | AI 小鲸窗口显示时触发 |
|
|
151
|
+
| close | - | AI 小鲸窗口关闭时触发 |
|
|
152
|
+
| stop | - | 停止生成内容时触发 |
|
|
153
|
+
| shortcut-click | shortcut: ShortCut | 点击快捷操作时触发,返回所点击的快捷操作对象 |
|
|
111
154
|
|
|
112
|
-
|
|
155
|
+
## 方法 (Methods)
|
|
113
156
|
|
|
114
|
-
|
|
157
|
+
| 方法名 | 参数 | 返回值 | 描述 |
|
|
158
|
+
|--------|------|--------|------|
|
|
159
|
+
| handleShow | - | - | 显示 AI 小鲸窗口 |
|
|
160
|
+
| handleStop | - | - | 停止当前正在生成的内容 |
|
|
161
|
+
| sendChat | options: {message, cite, shortcut} | - | 发送消息到 AI 小鲸 |
|
|
162
|
+
| handleShortcutClick | shortcut: ShortCut | - | 处理快捷操作点击 |
|
|
115
163
|
|
|
116
|
-
|
|
117
|
-
<button data-ai="{ type: 'button', data: 'xxx' }" class="ai-clickable">可点击的按钮</button>
|
|
118
|
-
<a data-ai="{ type: 'link', data: 'link url' }" class="ai-clickable" href="void">可点击的链接</a>
|
|
119
|
-
```
|
|
164
|
+
## 高级用法
|
|
120
165
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
```javascript
|
|
124
|
-
handleCustomButtonClick(dataAIValue) {
|
|
125
|
-
// 假设 'aiRef' 是组件的引用
|
|
126
|
-
const val = dataAIValue; //从 data-ai 属性获取的数据'
|
|
127
|
-
|
|
128
|
-
... // 业务处理逻辑,比如以下将`data-ai`上的字符串赋值到输入框
|
|
129
|
-
aiRef.value?.setInputMessage(val);
|
|
130
|
-
}
|
|
131
|
-
```
|
|
166
|
+
### Vue 3 快捷操作演示
|
|
132
167
|
|
|
133
|
-
|
|
168
|
+
```vue
|
|
169
|
+
<template>
|
|
170
|
+
<div>
|
|
171
|
+
<div class="article">
|
|
172
|
+
<h3>AI 技术的发展与应用</h3>
|
|
173
|
+
<p>{{ articleContent }}</p>
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
<div class="quick-actions">
|
|
177
|
+
<button @click="quickActions('解释', '解释一下这段内容:', articleTitle)">
|
|
178
|
+
解释标题
|
|
179
|
+
</button>
|
|
180
|
+
<button @click="quickActions('翻译', '翻译成英文:', articleTitle)">
|
|
181
|
+
翻译标题
|
|
182
|
+
</button>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<AIBlueking ref="aiBlueking" :url="apiUrl" />
|
|
186
|
+
</div>
|
|
187
|
+
</template>
|
|
134
188
|
|
|
135
|
-
|
|
189
|
+
<script lang="ts" setup>
|
|
190
|
+
import { ref } from 'vue';
|
|
191
|
+
import AIBlueking from '@blueking/ai-blueking';
|
|
192
|
+
import '@blueking/ai-blueking/dist/vue3/style.css';
|
|
136
193
|
|
|
137
|
-
|
|
194
|
+
const aiBlueking = ref(null);
|
|
195
|
+
const apiUrl = 'https://your-api-endpoint.com/assistant/';
|
|
196
|
+
const articleTitle = 'AI 技术的发展与应用';
|
|
197
|
+
const articleContent = '人工智能技术在近年来取得了突飞猛进的发展...';
|
|
138
198
|
|
|
139
|
-
|
|
199
|
+
const quickActions = (label, promptPrefix, cite) => {
|
|
200
|
+
aiBlueking.value?.handleShow();
|
|
201
|
+
|
|
202
|
+
aiBlueking.value?.sendChat({
|
|
203
|
+
message: label,
|
|
204
|
+
cite,
|
|
205
|
+
shortcut: {
|
|
206
|
+
label,
|
|
207
|
+
key: label.toLowerCase(),
|
|
208
|
+
prompt: `${promptPrefix} {{ SELECTED_TEXT }}`,
|
|
209
|
+
icon: 'icon-explanation'
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
};
|
|
213
|
+
</script>
|
|
214
|
+
```
|
|
140
215
|
|
|
141
|
-
|
|
216
|
+
### Vue 2 快捷操作演示
|
|
142
217
|
|
|
143
218
|
```vue
|
|
144
219
|
<template>
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
220
|
+
<div>
|
|
221
|
+
<div class="article">
|
|
222
|
+
<h3>AI 技术的发展与应用</h3>
|
|
223
|
+
<p>{{ articleContent }}</p>
|
|
224
|
+
</div>
|
|
225
|
+
|
|
226
|
+
<div class="quick-actions">
|
|
227
|
+
<button @click="quickActions('解释', '解释一下这段内容:', articleTitle)">
|
|
228
|
+
解释标题
|
|
229
|
+
</button>
|
|
230
|
+
<button @click="quickActions('翻译', '翻译成英文:', articleTitle)">
|
|
231
|
+
翻译标题
|
|
232
|
+
</button>
|
|
233
|
+
</div>
|
|
234
|
+
|
|
235
|
+
<AIBlueking ref="aiBlueking" :url="apiUrl" />
|
|
236
|
+
</div>
|
|
153
237
|
</template>
|
|
154
238
|
|
|
155
|
-
<script
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
// 如果是loading状态,直接覆盖
|
|
185
|
-
currentMessage.content = message;
|
|
186
|
-
currentMessage.status = MessageStatus.Success;
|
|
187
|
-
} else if (currentMessage?.status === MessageStatus.Success) {
|
|
188
|
-
// 根据 cover 参数决定是追加还是覆盖
|
|
189
|
-
currentMessage.content = cover ? message : currentMessage.content + message;
|
|
239
|
+
<script>
|
|
240
|
+
import AIBlueking from '@blueking/ai-blueking/vue2';
|
|
241
|
+
import '@blueking/ai-blueking/dist/vue2/style.css';
|
|
242
|
+
|
|
243
|
+
export default {
|
|
244
|
+
components: {
|
|
245
|
+
AIBlueking
|
|
246
|
+
},
|
|
247
|
+
data() {
|
|
248
|
+
return {
|
|
249
|
+
apiUrl: 'https://your-api-endpoint.com/assistant/',
|
|
250
|
+
articleTitle: 'AI 技术的发展与应用',
|
|
251
|
+
articleContent: '人工智能技术在近年来取得了突飞猛进的发展...'
|
|
252
|
+
};
|
|
253
|
+
},
|
|
254
|
+
methods: {
|
|
255
|
+
quickActions(label, promptPrefix, cite) {
|
|
256
|
+
|
|
257
|
+
this.$refs.aiBlueking.handleShow(); // 显示AI小鲸
|
|
258
|
+
|
|
259
|
+
this.$refs.aiBlueking.sendChat({ // 主动调用发送消息
|
|
260
|
+
message: label,
|
|
261
|
+
cite,
|
|
262
|
+
shortcut: {
|
|
263
|
+
label,
|
|
264
|
+
key: label.toLowerCase(),
|
|
265
|
+
prompt: `${promptPrefix} {{ SELECTED_TEXT }}`
|
|
266
|
+
}
|
|
267
|
+
});
|
|
190
268
|
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// 聊天结束
|
|
194
|
-
const handleEnd = (id: number | string) => {
|
|
195
|
-
loading.value = false;
|
|
196
|
-
const currentMessage = messages.value.at(-1);
|
|
197
|
-
// 在 loading 状态或思考状态下终止时,标记为错误
|
|
198
|
-
if (currentMessage?.status === MessageStatus.Loading || isThinking(currentMessage?.content || '')) {
|
|
199
|
-
currentMessage.content = '聊天内容已中断';
|
|
200
|
-
currentMessage.status = MessageStatus.Error;
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
// 错误处理
|
|
205
|
-
const handleError = (message: string, code: string | number, id: number | string) => {
|
|
206
|
-
if (message.includes('user authentication failed')) {
|
|
207
|
-
// 未登录,跳转登录
|
|
208
|
-
const loginUrl = new URL(process.env.BK_LOGIN_URL);
|
|
209
|
-
loginUrl.searchParams.append('c_url', location.origin);
|
|
210
|
-
window.location.href = loginUrl.href;
|
|
211
|
-
} else {
|
|
212
|
-
// 处理错误消息
|
|
213
|
-
const currentMessage = messages.value.at(-1);
|
|
214
|
-
currentMessage.status = MessageStatus.Error;
|
|
215
|
-
currentMessage.content = message;
|
|
216
|
-
loading.value = false;
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
const prefix = process.env.BK_API_URL_TMPL.replace('{api_name}', '<网关名>').replace('http', 'https');
|
|
221
|
-
const chatHelper = new ChatHelper(
|
|
222
|
-
`${prefix}/prod/bk_plugin/plugin_api/assistant/`,
|
|
223
|
-
handleStart,
|
|
224
|
-
handleReceiveMessage,
|
|
225
|
-
handleEnd,
|
|
226
|
-
handleError,
|
|
227
|
-
messages.value,
|
|
228
|
-
);
|
|
229
|
-
|
|
230
|
-
// 清空消息
|
|
231
|
-
const handleClear = () => {
|
|
232
|
-
messages.value.splice(0); // 必须使用这种方式清空消息, 不能使用 messages.value = [],否则 ChatHelper 无法感知消息数组的变化
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
// 发送消息
|
|
236
|
-
const handleSend = (args: ISendData) => {
|
|
237
|
-
// 记录当前消息记录
|
|
238
|
-
const chatHistory = [...messages.value];
|
|
239
|
-
// 添加一条消息
|
|
240
|
-
messages.value.push({
|
|
241
|
-
role: 'user',
|
|
242
|
-
content: args.content,
|
|
243
|
-
cite: args.cite,
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
// 根据参数构造输入内容
|
|
247
|
-
const input = args.prompt
|
|
248
|
-
? args.prompt // 如果有 prompt,直接使用
|
|
249
|
-
: args.cite
|
|
250
|
-
? `${args.content}: ${args.cite}` // 如果有 cite,拼接 content 和 cite
|
|
251
|
-
: args.content; // 否则只使用 content
|
|
252
|
-
|
|
253
|
-
// ai 消息,id是唯一标识当前流,调用 chatHelper.stop 的时候需要传入
|
|
254
|
-
chatHelper.stream(
|
|
255
|
-
{
|
|
256
|
-
inputs: {
|
|
257
|
-
input,
|
|
258
|
-
chat_history: chatHistory,
|
|
259
|
-
},
|
|
260
|
-
},
|
|
261
|
-
1,
|
|
262
|
-
);
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
// 暂停聊天
|
|
266
|
-
const handleStop = () => {
|
|
267
|
-
chatHelper.stop(1);
|
|
268
|
-
};
|
|
269
|
+
}
|
|
270
|
+
};
|
|
269
271
|
</script>
|
|
270
272
|
```
|
|
271
273
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
##### Vue3 示例:
|
|
274
|
+
### Vue 3 自定义提示词
|
|
275
275
|
|
|
276
276
|
```vue
|
|
277
277
|
<template>
|
|
278
278
|
<AIBlueking
|
|
279
|
-
|
|
280
|
-
:
|
|
281
|
-
:
|
|
282
|
-
:messages="messages"
|
|
283
|
-
:position-limit="positionLimit"
|
|
284
|
-
:prompts="prompts"
|
|
285
|
-
:scroll-loading="scrollLoading"
|
|
286
|
-
:scroll-loading-end="scrollLoadingEnd"
|
|
287
|
-
:size-limit="sizeLimit"
|
|
288
|
-
:start-position="startPosition"
|
|
289
|
-
@ai-click="handleAIClick"
|
|
290
|
-
@choose-prompt="handleChoosePrompt"
|
|
291
|
-
@clear="handleClear"
|
|
292
|
-
@close="handleClose"
|
|
293
|
-
@scroll-load="handleScrollLoad"
|
|
294
|
-
@send="handleSend"
|
|
295
|
-
@stop="handleStop"
|
|
279
|
+
ref="aiBlueking"
|
|
280
|
+
:url="apiUrl"
|
|
281
|
+
:prompts="customPrompts"
|
|
296
282
|
/>
|
|
297
283
|
</template>
|
|
298
|
-
<script setup lang="ts">
|
|
299
|
-
import { type ComponentInstance, ref } from 'vue';
|
|
300
|
-
|
|
301
|
-
import AIBlueking, { type IPrompt, type IMessage, RoleType, MessageStatus } from '@blueking/ai-blueking';
|
|
302
284
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
status: MessageStatus.Error,
|
|
317
|
-
},
|
|
318
|
-
{
|
|
319
|
-
content: '不对',
|
|
320
|
-
time: '2024-08-12 09:29',
|
|
321
|
-
role: RoleType.User,
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
content: '1+1=2',
|
|
325
|
-
time: '2024-08-12 09:31',
|
|
326
|
-
role: RoleType.Assistant,
|
|
327
|
-
status: MessageStatus.Loading,
|
|
328
|
-
},
|
|
329
|
-
{
|
|
330
|
-
content: '对了',
|
|
331
|
-
time: '2024-08-13 10:20',
|
|
332
|
-
role: RoleType.User,
|
|
333
|
-
},
|
|
334
|
-
{
|
|
335
|
-
content: '好的,任务已完成',
|
|
336
|
-
time: '2024-08-13 10:23',
|
|
337
|
-
role: RoleType.Assistant,
|
|
338
|
-
},
|
|
339
|
-
]);
|
|
340
|
-
// 内置 prompt
|
|
341
|
-
const prompts = [
|
|
342
|
-
{
|
|
343
|
-
id: 1,
|
|
344
|
-
content: '帮我计算1+1的结果',
|
|
345
|
-
},
|
|
346
|
-
{
|
|
347
|
-
id: 2,
|
|
348
|
-
content: '帮我计算2+2的结果',
|
|
349
|
-
},
|
|
350
|
-
];
|
|
351
|
-
|
|
352
|
-
// 处理ai消息的loading状态
|
|
353
|
-
const loading = ref(false);
|
|
354
|
-
// 聊天背景色
|
|
355
|
-
const background = '#f5f7fa';
|
|
356
|
-
// 头部背景色
|
|
357
|
-
const headBackground = 'linear-gradient(267deg, #2dd1f4 0%, #1482ff 95%)';
|
|
358
|
-
// 弹框位于屏幕四边的最小距离
|
|
359
|
-
const positionLimit = {
|
|
360
|
-
top: 0,
|
|
361
|
-
bottom: 0,
|
|
362
|
-
left: 0,
|
|
363
|
-
right: 0,
|
|
364
|
-
};
|
|
365
|
-
// 组件最小尺寸
|
|
366
|
-
const sizeLimit = {
|
|
367
|
-
height: 320,
|
|
368
|
-
width: 400,
|
|
369
|
-
};
|
|
370
|
-
// 初始位置
|
|
371
|
-
const startPosition = {
|
|
372
|
-
top: window.innerHeight - 560,
|
|
373
|
-
bottom: 0,
|
|
374
|
-
left: window.innerWidth - 400,
|
|
375
|
-
right: 0,
|
|
376
|
-
};
|
|
377
|
-
// 向上滚动加载
|
|
378
|
-
const scrollLoading = ref(false);
|
|
379
|
-
const scrollLoadingEnd = ref(false);
|
|
380
|
-
// 组件实例
|
|
381
|
-
const aiRef = ref<ComponentInstance<typeof AIBlueking>>();
|
|
382
|
-
|
|
383
|
-
const handleClear = () => {
|
|
384
|
-
console.log('trigger clear');
|
|
385
|
-
};
|
|
386
|
-
|
|
387
|
-
const handleSend = (val: string) => {
|
|
388
|
-
console.log('trigger send', val);
|
|
389
|
-
// args 包含:
|
|
390
|
-
// - content: 用户输入的内容
|
|
391
|
-
// - cite: 引用的内容(可选)
|
|
392
|
-
// - prompt: 使用的 prompt 模板(可选)
|
|
393
|
-
};
|
|
394
|
-
|
|
395
|
-
const handleStop = () => {
|
|
396
|
-
console.log('trigger stop');
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
const handleScrollLoad = () => {
|
|
400
|
-
scrollLoading.value = true;
|
|
401
|
-
setTimeout(() => {
|
|
402
|
-
// 模拟异步请求
|
|
403
|
-
messages.value.unshift(
|
|
404
|
-
...[
|
|
405
|
-
{
|
|
406
|
-
content: '1+1=?',
|
|
407
|
-
time: '2023-08-12 9:28',
|
|
408
|
-
role: RoleType.User,
|
|
409
|
-
},
|
|
410
|
-
{
|
|
411
|
-
content: '2',
|
|
412
|
-
time: '2023-08-12 9:30',
|
|
413
|
-
role: RoleType.Assistant,
|
|
414
|
-
},
|
|
415
|
-
],
|
|
416
|
-
);
|
|
417
|
-
// 设置状态
|
|
418
|
-
scrollLoading.value = false;
|
|
419
|
-
scrollLoadingEnd.value = true;
|
|
420
|
-
}, 1000);
|
|
421
|
-
};
|
|
422
|
-
|
|
423
|
-
const handleClose = () => {
|
|
424
|
-
console.log('trigger close');
|
|
425
|
-
};
|
|
426
|
-
|
|
427
|
-
const handleChoosePrompt = (prompt: IPrompt) => {
|
|
428
|
-
console.log('choose prompt', prompt);
|
|
429
|
-
};
|
|
430
|
-
|
|
431
|
-
const handleAIClick = (val: string) => {
|
|
432
|
-
aiRef.value?.setInputMessage(val);
|
|
433
|
-
};
|
|
285
|
+
<script lang="ts" setup>
|
|
286
|
+
import { ref } from 'vue';
|
|
287
|
+
import AIBlueking from '@blueking/ai-blueking';
|
|
288
|
+
import '@blueking/ai-blueking/dist/vue3/style.css';
|
|
289
|
+
|
|
290
|
+
const aiBlueking = ref(null);
|
|
291
|
+
const apiUrl = 'https://your-api-endpoint.com/assistant/';
|
|
292
|
+
|
|
293
|
+
const customPrompts = [
|
|
294
|
+
'我给一段文字,概括文字的主题和主要观点,找出支持主题的关键事实、论据或观点,使用中文回答。',
|
|
295
|
+
'假设你是一名关系型数据库专家,后续的对话我会直接描述我想要的查询效果,请告诉我如何写对应的SQL查询,并解释它,如果有多个版本的SQL,以MySQL数据库为主。',
|
|
296
|
+
'你是一名经验丰富的前端开发工程师,请帮我解决以下问题...'
|
|
297
|
+
];
|
|
434
298
|
</script>
|
|
435
299
|
```
|
|
436
300
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
Vue2 下,需要安装 npm 包,里面是 vue3 资源
|
|
440
|
-
|
|
441
|
-
```bash
|
|
442
|
-
npm i @blueking/ai-blueking
|
|
443
|
-
```
|
|
301
|
+
### Vue 2 自定义提示词
|
|
444
302
|
|
|
445
303
|
```vue
|
|
446
304
|
<template>
|
|
447
305
|
<AIBlueking
|
|
448
|
-
|
|
449
|
-
:
|
|
450
|
-
:
|
|
451
|
-
:messages="messages"
|
|
452
|
-
:position-limit="positionLimit"
|
|
453
|
-
:prompts="prompts"
|
|
454
|
-
:size-limit="sizeLimit"
|
|
455
|
-
:start-position="startPosition"
|
|
456
|
-
@choose-prompt="handleChoosePrompt"
|
|
457
|
-
@clear="handleClear"
|
|
458
|
-
@close="handleClose"
|
|
459
|
-
@send="handleSend"
|
|
460
|
-
@scroll="handleScroll"
|
|
461
|
-
@stop="handleStop"
|
|
306
|
+
ref="aiBlueking"
|
|
307
|
+
:url="apiUrl"
|
|
308
|
+
:prompts="customPrompts"
|
|
462
309
|
/>
|
|
463
310
|
</template>
|
|
464
|
-
<script lang="ts">
|
|
465
|
-
import { ref } from 'vue';
|
|
466
|
-
|
|
467
|
-
import AIBlueking from '@blueking/ai-blueking/vue2';
|
|
468
|
-
import '@blueking/ai-blueking/dist/vue2/style.css';
|
|
469
311
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
},
|
|
490
|
-
{
|
|
491
|
-
content: '不对',
|
|
492
|
-
role: 'user',
|
|
493
|
-
},
|
|
494
|
-
{
|
|
495
|
-
content: '1+1=2',
|
|
496
|
-
role: 'assistant',
|
|
497
|
-
status: 'loading',
|
|
498
|
-
},
|
|
499
|
-
{
|
|
500
|
-
content: '对了',
|
|
501
|
-
role: 'user',
|
|
502
|
-
},
|
|
503
|
-
{
|
|
504
|
-
content: '好的,任务已完成',
|
|
505
|
-
role: 'assistant',
|
|
506
|
-
},
|
|
507
|
-
],
|
|
508
|
-
prompts: [
|
|
509
|
-
{
|
|
510
|
-
id: 1,
|
|
511
|
-
content: '帮我计算1+1的结果',
|
|
512
|
-
},
|
|
513
|
-
{
|
|
514
|
-
id: 2,
|
|
515
|
-
content: '帮我计算2+2的结果',
|
|
516
|
-
},
|
|
517
|
-
],
|
|
518
|
-
loading: false,
|
|
519
|
-
background: '#f5f7fa',
|
|
520
|
-
headBackground: 'linear-gradient(267deg, #2dd1f4 0%, #1482ff 95%)',
|
|
521
|
-
positionLimit: {
|
|
522
|
-
top: 0,
|
|
523
|
-
bottom: 0,
|
|
524
|
-
left: 0,
|
|
525
|
-
right: 0,
|
|
526
|
-
},
|
|
527
|
-
sizeLimit: {
|
|
528
|
-
height: 320,
|
|
529
|
-
width: 400,
|
|
530
|
-
},
|
|
531
|
-
startPosition: {
|
|
532
|
-
top: window.innerHeight - 560,
|
|
533
|
-
bottom: 0,
|
|
534
|
-
left: window.innerWidth - 400,
|
|
535
|
-
right: 0,
|
|
536
|
-
},
|
|
537
|
-
};
|
|
538
|
-
},
|
|
539
|
-
methods: {
|
|
540
|
-
handleClear() {
|
|
541
|
-
console.log('trigger clear');
|
|
542
|
-
},
|
|
543
|
-
handleSend(val: string) {
|
|
544
|
-
console.log('trigger send', val);
|
|
545
|
-
},
|
|
546
|
-
handleClose() {
|
|
547
|
-
console.log('trigger close');
|
|
548
|
-
},
|
|
549
|
-
handleChoosePrompt(prompt) {
|
|
550
|
-
console.log('choose prompt', prompt);
|
|
551
|
-
},
|
|
552
|
-
handleScroll(event: Event) {
|
|
553
|
-
console.log('trigger scroll', event);
|
|
554
|
-
},
|
|
555
|
-
handleStop() {
|
|
556
|
-
console.log('trigger stop');
|
|
557
|
-
},
|
|
558
|
-
},
|
|
559
|
-
};
|
|
312
|
+
<script>
|
|
313
|
+
import AIBlueking from '@blueking/ai-blueking/vue2';
|
|
314
|
+
import '@blueking/ai-blueking/dist/vue2/style.css';
|
|
315
|
+
|
|
316
|
+
export default {
|
|
317
|
+
components: {
|
|
318
|
+
AIBlueking
|
|
319
|
+
},
|
|
320
|
+
data() {
|
|
321
|
+
return {
|
|
322
|
+
apiUrl: 'https://your-api-endpoint.com/assistant/',
|
|
323
|
+
customPrompts: [
|
|
324
|
+
'我给一段文字,概括文字的主题和主要观点,找出支持主题的关键事实、论据或观点,使用中文回答。',
|
|
325
|
+
'假设你是一名关系型数据库专家,后续的对话我会直接描述我想要的查询效果,请告诉我如何写对应的SQL查询,并解释它,如果有多个版本的SQL,以MySQL数据库为主。',
|
|
326
|
+
'你是一名经验丰富的前端开发工程师,请帮我解决以下问题...'
|
|
327
|
+
]
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
};
|
|
560
331
|
</script>
|
|
561
332
|
```
|
|
562
333
|
|
|
563
|
-
##
|
|
564
|
-
|
|
565
|
-
### 环境准备
|
|
566
|
-
|
|
567
|
-
1. 安装依赖
|
|
568
|
-
|
|
569
|
-
```bash
|
|
570
|
-
pnpm install
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
2. 启动开发服务器
|
|
574
|
-
|
|
575
|
-
```bash
|
|
576
|
-
pnpm run dev
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
3. 配置 hosts,以.woa.com 结尾的域名,以正常获取cookie
|
|
580
|
-
|
|
581
|
-
```bash
|
|
582
|
-
# 配置 hosts
|
|
583
|
-
echo "127.0.0.1 local.dev.woa.com" >> /etc/hosts
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
### Demo 运行模式
|
|
587
|
-
|
|
588
|
-
提供两种运行模式:
|
|
589
|
-
|
|
590
|
-
#### 1. 静态演示模式 (Static Demo)
|
|
591
|
-
|
|
592
|
-
- 无需配置环境变量
|
|
593
|
-
- 展示所有功能和配置项
|
|
594
|
-
- 通过 `/playground/static.vue` 查看示例
|
|
595
|
-
|
|
596
|
-
#### 2. 动态演示模式 (Dynamic Demo)
|
|
597
|
-
|
|
598
|
-
- 需要配置本地环境
|
|
599
|
-
- 模拟真实使用场景
|
|
600
|
-
- 通过 `/playground/dynamic.vue` 查看示例
|
|
334
|
+
## 框架差异注意事项
|
|
601
335
|
|
|
602
|
-
|
|
336
|
+
### Vue 2 与 Vue 3 的区别
|
|
603
337
|
|
|
604
|
-
|
|
338
|
+
1. **引入方式不同**:
|
|
339
|
+
- Vue 3: `import AIBlueking from '@blueking/ai-blueking'`
|
|
340
|
+
- Vue 2: `import AIBlueking from '@blueking/ai-blueking/vue2'`
|
|
605
341
|
|
|
606
|
-
|
|
342
|
+
2. **样式引入不同**:
|
|
343
|
+
- Vue 3: `import '@blueking/ai-blueking/dist/vue3/style.css'`
|
|
344
|
+
- Vue 2: `import '@blueking/ai-blueking/dist/vue2/style.css'`
|
|
607
345
|
|
|
346
|
+
3. **组件实例获取**:
|
|
347
|
+
- Vue 3: 通过 ref 值获取,如 `aiBlueking.value?.handleShow()`
|
|
348
|
+
- Vue 2: 通过 $refs 获取,如 `this.$refs.aiBlueking.handleShow()`
|
|
608
349
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
# 网站前缀
|
|
613
|
-
BK_API_GATEWAY_NAME = '<网关名称>'
|
|
614
|
-
|
|
615
|
-
# 静态资源路径
|
|
616
|
-
BK_API_URL_TMPL = 'https://{api_name}.example.com'
|
|
617
|
-
|
|
618
|
-
# 登录地址
|
|
619
|
-
BK_LOGIN_URL = 'http://login.example.com'
|
|
620
|
-
```
|
|
621
|
-
|
|
622
|
-
3. 登录态获取
|
|
350
|
+
4. **组件定义方式**:
|
|
351
|
+
- Vue 3: 使用 Composition API 或 Options API
|
|
352
|
+
- Vue 2: 使用 Options API
|
|
623
353
|
|
|
624
|
-
|
|
625
|
-
- Demo 中简化了登录相关的代码实现
|
|
626
|
-
- 未登录时会自动跳转到登录页面
|
|
354
|
+
## 通用注意事项
|
|
627
355
|
|
|
628
|
-
|
|
356
|
+
1. 必须设置有效的 `url` 属性,指向您的 AI 服务接口
|
|
357
|
+
2. 为了获得最佳体验,建议将 AI 小鲸放在全局组件中,以便在应用的任何地方都能访问
|
|
358
|
+
3. 快捷操作中的提示词模板使用 `{{ SELECTED_TEXT }}` 作为选中文本的占位符
|
|
359
|
+
4. Vue 2 中导入的是 `@blueking/ai-blueking/vue2`,而非根路径
|
|
629
360
|
|
|
630
|
-
|
|
361
|
+
## 示例项目
|
|
631
362
|
|
|
632
|
-
-
|
|
633
|
-
- 需要确保网关配置正确且有访问权限
|
|
363
|
+
可以参考 `packages/ai-blueking/playground/dynamic-demo.vue` 了解更多使用示例。
|
|
634
364
|
|
|
635
|
-
|
|
365
|
+
## 常见问题
|
|
636
366
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
- 其他错误会在界面上显示错误信息
|
|
367
|
+
1. **Q: AI 小鲸窗口如何调整大小?**
|
|
368
|
+
A: 用户可以通过拖动窗口边缘或右下角来调整窗口大小。
|
|
640
369
|
|
|
641
|
-
|
|
370
|
+
2. **Q: 如何实现选中文本弹出快捷操作?**
|
|
371
|
+
A: 这是 AI 小鲸的内置功能,设置 `enablePopup` 为 true 即可启用。
|
|
642
372
|
|
|
643
|
-
|
|
644
|
-
-
|
|
373
|
+
3. **Q: 在 Vue 2 项目中使用时遇到兼容性问题怎么办?**
|
|
374
|
+
A: 确保正确导入 Vue 2 版本的组件和样式,路径分别为 `@blueking/ai-blueking/vue2` 和 `@blueking/ai-blueking/dist/vue2/style.css`。
|