@tencentcloud/ai-desk-customer-vue 1.5.11 → 1.6.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.
Files changed (31) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/assets/audio-blue.svg +4 -0
  3. package/assets/audio_icon_1.svg +3 -0
  4. package/assets/audio_icon_2.svg +3 -0
  5. package/assets/audio_icon_3.svg +3 -0
  6. package/assets/keyboard-icon.svg +9 -0
  7. package/components/CustomerServiceChat/index-web.vue +10 -2
  8. package/components/CustomerServiceChat/message-input/index-web.vue +57 -10
  9. package/components/CustomerServiceChat/message-input/message-input-editor-web.vue +342 -11
  10. package/components/CustomerServiceChat/message-list/index-web.vue +13 -0
  11. package/components/CustomerServiceChat/message-list/message-elements/message-audio-web.vue +50 -78
  12. package/components/CustomerServiceChat/message-list/message-elements/message-bubble-web.vue +1 -1
  13. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/marked.ts +3 -2
  14. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-robot-welcome.vue +13 -6
  15. package/components/CustomerServiceChat/message-list/message-elements/message-text.vue +3 -2
  16. package/components/common/Toast/index-web.ts +16 -3
  17. package/components/common/Toast/index-web.vue +16 -6
  18. package/constant.ts +1 -0
  19. package/locales/en/TUIChat.ts +6 -2
  20. package/locales/fil/TUIChat.ts +6 -2
  21. package/locales/id/TUIChat.ts +76 -72
  22. package/locales/ja/TUIChat.ts +76 -72
  23. package/locales/ms/TUIChat.ts +76 -72
  24. package/locales/ru/TUIChat.ts +6 -2
  25. package/locales/th/TUIChat.ts +76 -72
  26. package/locales/vi/TUIChat.ts +76 -72
  27. package/locales/zh_cn/TUIChat.ts +6 -2
  28. package/locales/zh_tw/TUIChat.ts +6 -2
  29. package/package.json +2 -1
  30. package/server.ts +22 -3
  31. package/assets/keyboard_icon.png +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## 1.6.0 @2025.10.21
2
+
3
+ ### Features
4
+ - 支持用户端转人工成功后发送语音消息。
5
+ - 优化 emoji 表情的交互体验。
6
+ - 开启 url 识别特性时,确保消息安全。
7
+
8
+ ### Fixed
9
+ - 部分场景下,消息已读状态异常问题。
10
+ - 富文本换行问题。
11
+ - 切换账号登录可能导致的用户资料异常问题。
12
+ - 部分手机浏览器软键盘遮挡输入框问题。
13
+
1
14
  ## 1.5.11 @2025.9.28
2
15
 
3
16
  ### Features
@@ -0,0 +1,4 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M7 6C7 3.23858 9.23858 1 12 1C14.7614 1 17 3.23858 17 6V12.5C17 15.2614 14.7614 17.5 12 17.5C9.23858 17.5 7 15.2614 7 12.5V6ZM15 6V12.5C15 14.1569 13.6569 15.5 12 15.5C10.3431 15.5 9 14.1569 9 12.5V6C9 4.34315 10.3431 3 12 3C13.6569 3 15 4.34315 15 6Z" fill="#1C66E5"/>
3
+ <path d="M3 11V12.5C3 17.1326 6.50005 20.9476 11 21.4451V24H13V21.4451C17.5 20.9476 21 17.1326 21 12.5V11H19V12.5C19 16.366 15.866 19.5 12 19.5C8.13401 19.5 5 16.366 5 12.5V11H3Z" fill="#1C66E5"/>
4
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M11.4131 6.32129C11.0189 6.76465 10.7773 7.34741 10.7773 7.9873C10.7775 8.62651 11.0195 9.20745 11.4131 9.65039L13.2852 7.98633L11.4131 6.32129Z" fill="white" style="fill:white;fill-opacity:1;"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M8.59863 3.82031C7.6133 4.92851 7.0137 6.38793 7.01367 7.9873L7.02148 8.30957C7.09619 9.782 7.68002 11.1194 8.59863 12.1523L9.71973 11.1553C8.97051 10.3125 8.51389 9.20362 8.51367 7.9873C8.5137 6.77028 8.9699 5.65959 9.71973 4.81641L8.59863 3.82031ZM11.4131 6.32129C11.0189 6.76465 10.7773 7.34741 10.7773 7.9873C10.7775 8.62651 11.0195 9.20745 11.4131 9.65039L13.2852 7.98633L11.4131 6.32129Z" fill="white" style="fill:white;fill-opacity:1;"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M5.78613 1.32031C4.20943 3.09333 3.25002 5.42813 3.25 7.9873L3.2627 8.50391C3.38231 10.8598 4.31628 12.9998 5.78613 14.6523L6.90723 13.6562C5.56634 12.1486 4.75019 10.1637 4.75 7.9873C4.75002 5.81048 5.56603 3.82441 6.90723 2.31641L5.78613 1.32031ZM8.59863 3.82031C7.6133 4.92851 7.0137 6.38793 7.01367 7.9873L7.02148 8.30957C7.09619 9.782 7.68002 11.1194 8.59863 12.1523L9.71973 11.1553C8.97051 10.3125 8.51389 9.20362 8.51367 7.9873C8.5137 6.77028 8.9699 5.65959 9.71973 4.81641L8.59863 3.82031ZM11.4131 6.32129C11.0189 6.76465 10.7773 7.34741 10.7773 7.9873C10.7775 8.62651 11.0195 9.20745 11.4131 9.65039L13.2852 7.98633L11.4131 6.32129Z" fill="white" style="fill:white;fill-opacity:1;"/>
3
+ </svg>
@@ -0,0 +1,9 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <circle cx="12" cy="12" r="10" stroke="#1C66E5" stroke-width="2"/>
3
+ <circle cx="12" cy="9.5" r="1.5" fill="#1C66E5"/>
4
+ <circle cx="12" cy="14.5" r="1.5" fill="#1C66E5"/>
5
+ <circle cx="7.5" cy="9.5" r="1.5" fill="#1C66E5"/>
6
+ <circle cx="7.5" cy="14.5" r="1.5" fill="#1C66E5"/>
7
+ <circle cx="16.5" cy="9.5" r="1.5" fill="#1C66E5"/>
8
+ <circle cx="16.5" cy="14.5" r="1.5" fill="#1C66E5"/>
9
+ </svg>
@@ -57,6 +57,7 @@
57
57
  :placeholder="TUITranslateService.t('TUIChat.请输入消息')"
58
58
  :inputToolbarDisplayType="inputToolbarDisplayType"
59
59
  :inputToolbarList="props.inputToolbarList"
60
+ :enableSendingAudio="props.enableSendingAudio"
60
61
  @changeToolbarDisplayType="changeToolbarDisplayType"
61
62
  @emojiShow="emojiShow"
62
63
  @toolShow="toolShow"
@@ -149,6 +150,7 @@ interface IProps {
149
150
  enableAINote?: number;
150
151
  enableURLDetection?: number;
151
152
  headerConfig?: IHeaderConfig;
153
+ enableSendingAudio?: number;
152
154
  }
153
155
 
154
156
  const emits = defineEmits(['closeChat']);
@@ -192,6 +194,7 @@ const props = withDefaults(defineProps<IProps>(), {
192
194
  enableAINote: 1,
193
195
  langList: () => [],
194
196
  enableURLDetection: 0,
197
+ enableSendingAudio: 0,
195
198
  });
196
199
 
197
200
  const loginCustomerUIKit = () => {
@@ -329,6 +332,11 @@ try {
329
332
  }
330
333
 
331
334
  onMounted(() => {
335
+ // 如果组件挂载在 sdk login 之后,需再次设置 displayMessageReadReceipt,确保状态准确
336
+ if (TUIChatEngine.isReady()) {
337
+ switchReadStatus(state.get('showReadStatus'));
338
+ }
339
+
332
340
  TUIStore.watch(StoreName.CONV, {
333
341
  currentConversationID: onCurrentConversationIDUpdate,
334
342
  });
@@ -436,8 +444,8 @@ function toolShow(){
436
444
  toolShowH5.value = !toolShowH5.value;
437
445
  }
438
446
 
439
- function blurToolAndEmojiH5(){
440
- if(emojiOpen.value === true){
447
+ function blurToolAndEmojiH5() {
448
+ if (emojiOpen.value === true) {
441
449
  emojiOpen.value = false;
442
450
  }
443
451
  toolShowH5.value = false;
@@ -9,16 +9,21 @@
9
9
  !isPC && 'message-input-container-h5',
10
10
  ]"
11
11
  >
12
+ <div v-if="shouldShowAudio" class="audio-icon" @click="audioShow">
13
+ <Icon :file="isInAudioMode ? keyboardIcon : audioIcon" width="24px" height="24px"/>
14
+ </div>
12
15
  <MessageInputEditor
13
16
  ref="editor"
14
- :placeholder="props.placeholder"
17
+ :placeholder="placeholder"
15
18
  :isMuted="props.isMuted"
16
19
  :muteText="props.muteText"
17
20
  :enableInput="props.enableInput"
18
21
  :enableTyping="props.enableTyping"
19
22
  :enableDragUpload="props.enableDragUpload"
20
- :hasInputTool="shouldShowToolbar"
21
- :hasEmojiTool="shouldShowEmoji"
23
+ :isInAudioMode="isInAudioMode"
24
+ :shouldShowToolbar="shouldShowToolbar"
25
+ :shouldShowEmoji="shouldShowEmoji"
26
+ :shouldShowAudio="shouldShowAudio"
22
27
  @sendMessage="sendMessage"
23
28
  @onTyping="onTyping"
24
29
  @blurToolAndEmojiH5="blurToolAndEmojiH5"
@@ -47,6 +52,7 @@ import {
47
52
  TUIStore,
48
53
  StoreName,
49
54
  IConversationModel,
55
+ TUITranslateService
50
56
  } from '@tencentcloud/chat-uikit-engine';
51
57
  import vue from '../../../adapter-vue';
52
58
  import MessageInputEditor from './message-input-editor-web.vue';
@@ -59,14 +65,13 @@ import Icon from '../../common/Icon.vue';
59
65
  import emojiIcon from '../../../assets/emoji.png';
60
66
  import toolIcon from '../../../assets/more_tools.png';
61
67
  import sendButtonIcon from '../../../assets/send_button_h5.svg';
68
+ import audioIcon from '../../../assets/audio-blue.svg';
69
+ import keyboardIcon from '../../../assets/keyboard-icon.svg';
62
70
  import { INPUT_TOOLBAR_TYPE } from '../../../constant';
71
+ import { onUnmounted } from 'vue';
63
72
  const { ref, onMounted, onBeforeUnmount, computed } = vue;
64
73
 
65
74
  const props = defineProps({
66
- placeholder: {
67
- type: String,
68
- default: 'this is placeholder',
69
- },
70
75
  isMuted: {
71
76
  type: Boolean,
72
77
  default: true,
@@ -91,18 +96,40 @@ const props = defineProps({
91
96
  type: Array,
92
97
  default: undefined,
93
98
  },
99
+ enableSendingAudio: {
100
+ type: Number,
101
+ default: 0,
102
+ },
94
103
  });
95
104
 
96
105
  const emit = defineEmits(['messageSent', 'resetReplyOrReference', 'onTyping','scrollToLatestMessage','changeToolbarDisplayType','insertEmoji','emojiShow','toolShow','blurToolAndEmojiH5']);
106
+ const placeholder = ref(TUITranslateService.t('TUIChat.请输入消息'));
97
107
  const editor = ref<InstanceType<typeof MessageInputEditor>>();
98
108
  const currentConversation = ref<IConversationModel>();
99
109
  const h5Dialog = ref<HTMLElement>();
100
110
  const showSendButton = ref(false);
111
+ const isInHumanService = ref(false);
101
112
  let quoteMessageCloudCustomData:string = '';
113
+ const isInAudioMode = ref(false);
102
114
 
103
115
  onMounted(() => {
104
116
  // document.addEventListener('click', handleClick);
105
- })
117
+ TUIStore.watch(StoreName.CUSTOM, {
118
+ isInHumanService: onInHumanServiceUpdate,
119
+ });
120
+ });
121
+
122
+ onUnmounted(() => {
123
+ TUIStore.unwatch(StoreName.CUSTOM, {
124
+ isInHumanService: onInHumanServiceUpdate,
125
+ });
126
+ });
127
+
128
+ const onInHumanServiceUpdate = (data: {conversationID: string, value: boolean}) => {
129
+ if (data && data.conversationID === currentConversation.value.conversationID) {
130
+ isInHumanService.value = data.value;
131
+ }
132
+ };
106
133
 
107
134
  onBeforeUnmount(() => {
108
135
  // document.removeEventListener('click', handleClick);
@@ -177,18 +204,28 @@ const blurToolAndEmojiH5 = () =>{
177
204
  emit('blurToolAndEmojiH5');
178
205
  }
179
206
 
207
+ const audioShow = () => {
208
+ isInAudioMode.value = !isInAudioMode.value;
209
+ placeholder.value = isInAudioMode.value ? TUITranslateService.t('TUIChat.按住说话') : TUITranslateService.t('TUIChat.请输入消息');
210
+ emit('blurToolAndEmojiH5');
211
+ }
212
+
180
213
  const shouldShowToolbar = computed(() => {
181
214
  if (props.inputToolbarList !== undefined && props.inputToolbarList.length === 0) {
182
215
  return false;
183
216
  }
184
- if (props.inputToolbarList !== undefined && props.inputToolbarList.length === 1 && props.inputToolbarList[0]?.presetId === INPUT_TOOLBAR_TYPE.EMOJI) {
217
+ if (props.inputToolbarList !== undefined && props.inputToolbarList.length === 1 && (props.inputToolbarList[0]?.presetId === INPUT_TOOLBAR_TYPE.EMOJI || props.inputToolbarList[0]?.presetId === INPUT_TOOLBAR_TYPE.AUDIO)) {
185
218
  return false;
186
219
  }
187
220
  return true;
188
221
  });
189
222
 
190
223
  const shouldShowEmoji = computed(() => {
191
- return props.inputToolbarList === undefined || props.inputToolbarList.some(item => item.presetId === INPUT_TOOLBAR_TYPE.EMOJI && item.isEnabled === 1);
224
+ return (props.inputToolbarList === undefined || props.inputToolbarList.some(item => item.presetId === INPUT_TOOLBAR_TYPE.EMOJI && item.isEnabled === 1)) && !isInAudioMode.value;
225
+ });
226
+
227
+ const shouldShowAudio = computed(() => {
228
+ return isH5 && isInHumanService.value && (props.enableSendingAudio === 1 || (props.inputToolbarList !== undefined && props.inputToolbarList.some(item => item.presetId === INPUT_TOOLBAR_TYPE.AUDIO && item.isEnabled === 1)));
192
229
  });
193
230
 
194
231
  defineExpose({
@@ -246,6 +283,16 @@ defineExpose({
246
283
  align-items: center;
247
284
  }
248
285
 
286
+ .audio-icon {
287
+ background: #fff;
288
+ margin-left: 10px;
289
+ border-radius: 10px;
290
+ padding: 5px;
291
+ display: flex;
292
+ justify-content: center;
293
+ align-items: center;
294
+ }
295
+
249
296
  .input-tool-dialog{
250
297
  height: fit-content;
251
298
  background: #fff;