@syfei49/mini-dynamic-renderer 1.0.2 → 1.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/README.md +15 -5
- package/components/ly-ai-assistant/ly-ai-assistant.vue +32 -5
- package/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @syfei49/mini-dynamic-renderer
|
|
2
2
|
|
|
3
|
-
uni-app 浮层 AI 客服插件(v1.0.
|
|
3
|
+
uni-app 浮层 AI 客服插件(v1.0.4)。在指定页面右下角显示 AI 浮层图标,点击后从底部弹出抽屉聊天面板,支持文字、图片、拍照/相册上传及 `[NEED_ICON]` 分类图标引导。
|
|
4
4
|
|
|
5
5
|
## 安装
|
|
6
6
|
|
|
@@ -13,11 +13,10 @@ npm install @syfei49/mini-dynamic-renderer
|
|
|
13
13
|
|
|
14
14
|
## 接入
|
|
15
15
|
|
|
16
|
-
### 1. App.vue
|
|
16
|
+
### 1. App.vue 初始化
|
|
17
17
|
|
|
18
18
|
```vue
|
|
19
19
|
<script setup>
|
|
20
|
-
import LyAiAssistant from '@syfei49/mini-dynamic-renderer/components/ly-ai-assistant/ly-ai-assistant.vue'
|
|
21
20
|
import { init } from '@syfei49/mini-dynamic-renderer'
|
|
22
21
|
|
|
23
22
|
init({
|
|
@@ -30,6 +29,17 @@ init({
|
|
|
30
29
|
loginPage: '/pages/login/login?noauto=1'
|
|
31
30
|
})
|
|
32
31
|
</script>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 2. 在需要显示浮层的页面引入组件
|
|
35
|
+
|
|
36
|
+
以 `pages/user/user.vue` 为例:
|
|
37
|
+
|
|
38
|
+
```vue
|
|
39
|
+
<script setup>
|
|
40
|
+
import LyAiAssistant from '@syfei49/mini-dynamic-renderer/components/ly-ai-assistant/ly-ai-assistant.vue'
|
|
41
|
+
import { openChat } from '@syfei49/mini-dynamic-renderer'
|
|
42
|
+
</script>
|
|
33
43
|
|
|
34
44
|
<template>
|
|
35
45
|
<view>
|
|
@@ -39,7 +49,7 @@ init({
|
|
|
39
49
|
</template>
|
|
40
50
|
```
|
|
41
51
|
|
|
42
|
-
> `
|
|
52
|
+
> 微信小程序 `App.vue` 的 template 不会被渲染,所以浮层组件需要放在具体页面里。
|
|
43
53
|
|
|
44
54
|
### 2. 在任意页面打开抽屉(可选)
|
|
45
55
|
|
|
@@ -79,6 +89,6 @@ openChat()
|
|
|
79
89
|
|
|
80
90
|
## 版本说明
|
|
81
91
|
|
|
82
|
-
- **v1.0.
|
|
92
|
+
- **v1.0.4**:uni-app 浮层 AI 插件、抽屉聊天、迁移 aiChat 全能力、文档拆分
|
|
83
93
|
- v1.0.0:wx.request 拦截 + hello world 弹窗(测试版)
|
|
84
94
|
- 后续版本将根据后端 `renderConfig` 动态渲染更多组件类型
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
</view>
|
|
7
7
|
|
|
8
8
|
<view v-if="opened" class="ly-ai-overlay" @click.self="closeChat">
|
|
9
|
-
<view class="ly-ai-drawer">
|
|
9
|
+
<view class="ly-ai-drawer" :style="drawerStyle">
|
|
10
10
|
<view class="ly-ai-header">
|
|
11
11
|
<text class="ly-ai-title">AI 智能客服</text>
|
|
12
12
|
<view class="ly-ai-close" @click="closeChat">×</view>
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
<view class="ly-ai-input-bar">
|
|
56
56
|
<view class="ly-ai-attach-btn" :class="{ disabled: loading || uploading }" @click="chooseImage">+</view>
|
|
57
57
|
<input class="ly-ai-chat-input" :value="inputText" placeholder="请输入您的问题" confirm-type="send"
|
|
58
|
-
:disabled="loading || uploading" @input="onInput" @confirm="handleSend" />
|
|
58
|
+
:disabled="loading || uploading" :adjust-position="false" :hold-keyboard="true" @input="onInput" @confirm="handleSend" />
|
|
59
59
|
<view class="ly-ai-send-btn" :class="{ disabled: loading || uploading || !canSend }" @click="handleSend">发送</view>
|
|
60
60
|
</view>
|
|
61
61
|
</template>
|
|
@@ -90,6 +90,7 @@
|
|
|
90
90
|
const quickQuestions = ref([])
|
|
91
91
|
const scrollIntoView = ref('')
|
|
92
92
|
const floatIconUrl = ref('')
|
|
93
|
+
const keyboardHeight = ref(0)
|
|
93
94
|
|
|
94
95
|
const canSend = computed(() => {
|
|
95
96
|
return !!(inputText.value && inputText.value.trim()) || !!pendingImageUrl.value
|
|
@@ -102,9 +103,16 @@
|
|
|
102
103
|
}
|
|
103
104
|
})
|
|
104
105
|
|
|
106
|
+
const drawerStyle = computed(() => {
|
|
107
|
+
return {
|
|
108
|
+
bottom: keyboardHeight.value + 'px'
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
|
|
105
112
|
let updateHandler = null
|
|
106
113
|
let openHandler = null
|
|
107
114
|
let closeHandler = null
|
|
115
|
+
let keyboardHandler = null
|
|
108
116
|
|
|
109
117
|
function syncState(snapshot) {
|
|
110
118
|
messages.value = snapshot.messages || []
|
|
@@ -144,11 +152,13 @@
|
|
|
144
152
|
return
|
|
145
153
|
}
|
|
146
154
|
opened.value = true
|
|
155
|
+
keyboardHeight.value = 0
|
|
147
156
|
scrollToBottom()
|
|
148
157
|
}
|
|
149
158
|
|
|
150
159
|
function closeChat() {
|
|
151
160
|
opened.value = false
|
|
161
|
+
keyboardHeight.value = 0
|
|
152
162
|
chatService.closeConversation()
|
|
153
163
|
}
|
|
154
164
|
|
|
@@ -214,14 +224,25 @@
|
|
|
214
224
|
}
|
|
215
225
|
openHandler = function () {
|
|
216
226
|
opened.value = true
|
|
227
|
+
keyboardHeight.value = 0
|
|
217
228
|
scrollToBottom()
|
|
218
229
|
}
|
|
219
230
|
closeHandler = function () {
|
|
220
231
|
opened.value = false
|
|
232
|
+
keyboardHeight.value = 0
|
|
233
|
+
}
|
|
234
|
+
keyboardHandler = function (res) {
|
|
235
|
+
keyboardHeight.value = res.height || 0
|
|
236
|
+
if (keyboardHeight.value > 0) {
|
|
237
|
+
scrollToBottom()
|
|
238
|
+
}
|
|
221
239
|
}
|
|
222
240
|
chatService.onUpdate(updateHandler)
|
|
223
241
|
chatService.onOpen(openHandler)
|
|
224
242
|
chatService.onClose(closeHandler)
|
|
243
|
+
if (typeof uni.onKeyboardHeightChange === 'function') {
|
|
244
|
+
uni.onKeyboardHeightChange(keyboardHandler)
|
|
245
|
+
}
|
|
225
246
|
syncState(chatService.getSnapshot())
|
|
226
247
|
checkVisible()
|
|
227
248
|
})
|
|
@@ -236,6 +257,9 @@
|
|
|
236
257
|
if (closeHandler) {
|
|
237
258
|
chatService.offClose(closeHandler)
|
|
238
259
|
}
|
|
260
|
+
if (keyboardHandler && typeof uni.offKeyboardHeightChange === 'function') {
|
|
261
|
+
uni.offKeyboardHeightChange(keyboardHandler)
|
|
262
|
+
}
|
|
239
263
|
})
|
|
240
264
|
|
|
241
265
|
onShow(() => {
|
|
@@ -276,18 +300,20 @@
|
|
|
276
300
|
bottom: 0;
|
|
277
301
|
z-index: 10000;
|
|
278
302
|
background: rgba(0, 0, 0, 0.4);
|
|
279
|
-
display: flex;
|
|
280
|
-
flex-direction: column;
|
|
281
|
-
justify-content: flex-end;
|
|
282
303
|
}
|
|
283
304
|
|
|
284
305
|
.ly-ai-drawer {
|
|
306
|
+
position: absolute;
|
|
307
|
+
left: 0;
|
|
308
|
+
right: 0;
|
|
309
|
+
bottom: 0;
|
|
285
310
|
height: 82vh;
|
|
286
311
|
background: #f5f6f8;
|
|
287
312
|
border-radius: 32rpx 32rpx 0 0;
|
|
288
313
|
display: flex;
|
|
289
314
|
flex-direction: column;
|
|
290
315
|
overflow: hidden;
|
|
316
|
+
transition: bottom 0.2s ease;
|
|
291
317
|
}
|
|
292
318
|
|
|
293
319
|
.ly-ai-header {
|
|
@@ -322,6 +348,7 @@
|
|
|
322
348
|
.ly-ai-list {
|
|
323
349
|
flex: 1;
|
|
324
350
|
padding: 24rpx;
|
|
351
|
+
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
|
|
325
352
|
box-sizing: border-box;
|
|
326
353
|
}
|
|
327
354
|
|
package/index.js
CHANGED