@tencentcloud/ai-desk-customer-vue 1.5.6 → 1.5.8

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 (58) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/assets/feedback_dislike_after.svg +1 -1
  3. package/assets/feedback_dislike_before.svg +2 -9
  4. package/assets/feedback_dislike_hover.svg +2 -9
  5. package/assets/feedback_like_after.svg +2 -13
  6. package/assets/feedback_like_before.svg +2 -9
  7. package/assets/feedback_like_hover.svg +2 -9
  8. package/components/CustomerServiceChat/chat-header/index-web.vue +10 -10
  9. package/components/CustomerServiceChat/feedback-modal/index.vue +391 -0
  10. package/components/CustomerServiceChat/index-web.vue +26 -0
  11. package/components/CustomerServiceChat/message-input/message-input-editor-web.vue +0 -1
  12. package/components/CustomerServiceChat/message-input/message-input-quote/index.vue +0 -3
  13. package/components/CustomerServiceChat/message-input-toolbar/index-web.vue +4 -2
  14. package/components/CustomerServiceChat/message-list/bottom-quick-order/index.vue +0 -1
  15. package/components/CustomerServiceChat/message-list/index-web.vue +90 -61
  16. package/components/CustomerServiceChat/message-list/message-elements/feedback-button.vue +96 -251
  17. package/components/CustomerServiceChat/message-list/message-elements/message-bubble-web.vue +51 -16
  18. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-concurrency-limit.vue +0 -2
  19. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-ivr-form/form-branch.vue +0 -1
  20. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-branch/branch-pc.vue +0 -2
  21. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-mobile.vue +5 -9
  22. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-pc.vue +0 -1
  23. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-order.vue +0 -1
  24. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-product-card.vue +0 -1
  25. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-rating/message-rating-star.vue +0 -1
  26. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-stream.vue +0 -1
  27. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-transfer-with-desc.vue +0 -1
  28. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/styles/common.scss +0 -2
  29. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-plugin-layout-web.vue +16 -0
  30. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-plugin-web.vue +18 -0
  31. package/components/CustomerServiceChat/message-list/message-elements/message-quote/index-web.vue +0 -3
  32. package/components/CustomerServiceChat/message-list/message-elements/message-text.vue +0 -1
  33. package/components/CustomerServiceChat/message-list/message-elements/message-timestamp.vue +0 -1
  34. package/components/CustomerServiceChat/message-list/message-elements/read-status/index.vue +4 -2
  35. package/components/CustomerServiceChat/message-list/scroll-button/index.vue +8 -4
  36. package/components/CustomerServiceChat/message-list/style/web.scss +0 -2
  37. package/components/CustomerServiceChat/message-toolbar-button/index.vue +8 -5
  38. package/components/CustomerServiceChat/style/common.scss +4 -0
  39. package/components/CustomerServiceChat/style/web.scss +2 -1
  40. package/components/common/BottomPopup/style/h5.scss +0 -1
  41. package/components/common/Dialog/style/color.scss +0 -1
  42. package/components/common/Toast/index-web.vue +1 -1
  43. package/constant.ts +2 -0
  44. package/locales/en/aidesk.ts +18 -15
  45. package/locales/fil/aidesk.ts +17 -15
  46. package/locales/id/aidesk.ts +17 -15
  47. package/locales/ja/aidesk.ts +17 -15
  48. package/locales/ms/aidesk.ts +17 -15
  49. package/locales/ru/aidesk.ts +17 -15
  50. package/locales/th/aidesk.ts +17 -15
  51. package/locales/vi/aidesk.ts +17 -15
  52. package/locales/zh_cn/aidesk.ts +17 -14
  53. package/locales/zh_tw/aidesk.ts +17 -15
  54. package/package.json +1 -1
  55. package/server.ts +5 -2
  56. package/utils/index.ts +6 -0
  57. package/utils/utils.ts +42 -0
  58. package/assets/customer_avatar.png +0 -0
@@ -1,15 +1,16 @@
1
1
  <template>
2
2
  <div>
3
- <div class="feedback-container">
3
+ <div :class="[isH5 ? 'feedback-container-h5' : '', 'feedback-container']">
4
4
  <div
5
5
  class="feedback-like"
6
- @mouseenter="isFeedbackLikeHover = true"
7
- @mouseleave="isFeedbackLikeHover = false"
8
- @click="feedbackLikeClick"
6
+ @mouseenter="isLikeIconHover = true"
7
+ @mouseleave="isLikeIconHover = false"
8
+ @click="onLikeIconClick"
9
9
  >
10
- <Icon :file="feedbackLikeIcon" width="16px" height="16px"/>
10
+ <Icon :file="likeIcon" width="16px" height="16px"/>
11
11
  <div
12
12
  class="tooltip"
13
+ v-if="isPC"
13
14
  >
14
15
  {{ TUITranslateService.t("AIDesk.满意") }}
15
16
  <div class="tooltip-arrow"></div>
@@ -18,179 +19,137 @@
18
19
  <span class="divider"></span>
19
20
  <div
20
21
  class="feedback-dislike"
21
- @mouseenter="isFeedbackDislikeHover = true"
22
- @mouseleave="isFeedbackDislikeHover = false"
23
- @click="feedbackDislikeClick"
22
+ @mouseenter="isDislikeIconHover = true"
23
+ @mouseleave="isDislikeIconHover = false"
24
+ @click="onDislikeIconClick"
24
25
  >
25
- <Icon :file="feedbackDislikeIcon" width="16px" height="16px" @click="dislickClick"/>
26
+ <Icon :file="dislikeIcon" width="16px" height="16px"/>
26
27
  <div
27
28
  class="tooltip"
29
+ v-if="isPC"
28
30
  >
29
31
  {{ TUITranslateService.t("AIDesk.不满意") }}
30
32
  <div class="tooltip-arrow"></div>
31
33
  </div>
32
34
  </div>
33
35
  </div>
34
- <div v-if="showDialog" class="feedback-dialog">
35
- <div class="feedback-dialog-main">
36
- <div class="feedback-dialog-header">
37
- <div class="dialog-header-content">
38
- <Icon :file="GreenCheck" width="24px" height="24px"/>
39
- <span class="dialog-header-title">
40
- {{ TUITranslateService.t("AIDesk.感谢您的反馈,我们会持续优化改进") }}
41
- </span>
42
- </div>
43
- <Icon :file="DialogCloseIcon" width="24px" height="24px" @click="closeDialog"/>
44
- </div>
45
-
46
- <div class="dialog-select">
47
- <span class="dialog-session-title">
48
- {{ TUITranslateService.t("AIDesk.您遇到了哪方面的问题") }}
49
- </span>
50
- <div class="dialog-button-list">
51
- <div class="dialog-button-row" v-for="(item) in feedbackButton">
52
- <div :class="['dialog-button',item.isSelected ? 'dialog-button-selected': '']" @click="dialogButtonClick(item)">
53
- {{ TUITranslateService.t(`AIDesk.${item.text}`) }}
54
- </div>
55
- </div>
56
- </div>
57
- </div>
58
-
59
- <div class="dialog-other">
60
- <span class="dialog-session-title">
61
- {{ TUITranslateService.t("AIDesk.其他反馈内容") }}
62
- </span>
63
- <textarea type="text" :placeholder="TUITranslateService.t('AIDesk.请输入内容')" v-model="feedbackText" class="dialog-other-input"/>
64
- </div>
65
- <div class="dialog-foot">
66
- <div class="dialog-submit" @click="submitBadFeeback">
67
- {{ TUITranslateService.t("AIDesk.提交") }}
68
- </div>
69
- <div class="dialog-cancel" @click="closeDialog">
70
- {{ TUITranslateService.t("AIDesk.取消") }}
71
- </div>
72
- </div>
73
- </div>
74
- </div>
75
36
  </div>
76
37
  </template>
77
38
  <script lang="ts">
78
39
  import vue from '../../../../adapter-vue';
79
40
  import Icon from '../../../common/Icon.vue';
80
- import { TUITranslateService } from '@tencentcloud/chat-uikit-engine';
41
+ import { IMessageModel, TUITranslateService, TUIChatEngine } from '@tencentcloud/chat-uikit-engine';
81
42
  import FeedbackLikeBefore from '../../../../assets/feedback_like_before.svg';
82
43
  import FeedbackLikeAfter from '../../../../assets/feedback_like_after.svg';
83
44
  import FeedbackLikeHover from '../../../../assets/feedback_like_hover.svg';
84
45
  import FeedbackDislikeBefore from '../../../../assets/feedback_dislike_before.svg';
85
46
  import FeedbackDislikeAfter from '../../../../assets/feedback_dislike_after.svg';
86
47
  import FeedbackDislikeHover from '../../../../assets/feedback_dislike_hover.svg';
87
- import GreenCheck from '../../../../assets/green_check.svg';
88
- import DialogCloseIcon from '../../../../assets/feedback_dialog_close.svg';
48
+ import { isPC, isH5 } from '../../../../utils/env';
89
49
  const { ref,computed } = vue;
90
50
 
91
51
  export default {
92
52
  components:{
93
53
  Icon
94
54
  },
95
- setup(){
96
- const isFeedbackLikeHover = ref(false);
97
- const isFeedbackLikeClick = ref(false);
98
- const isFeedbackDislikeHover = ref(false);
99
- const isFeedbackDislikeClick = ref(false);
100
- const showDialog = ref(false);
101
- const feedbackText = ref('');
102
- const feedbackButton = ref([
103
- { id:'nonResponsiveAnswer', text: '答非所问', isSelected: false },
104
- { id:'unmatchedContentRetrieval', text: '未匹配相关内容', isSelected: false },
105
- { id:'incorrectInfoAnswer', text: '信息错误', isSelected: false },
106
- { id:'contextMisunderstandingQuery', text: '上下文理解错误', isSelected: false },
107
- { id:'nonStandardFormatAnswer', text: '格式不规范', isSelected: false },
108
- { id:'incompleteContentRetrieval', text: '内容不完整', isSelected: false },
109
- ]);
110
- const feedbackReply = {
111
- isSupport:1, //1:点赞。0:点踩
112
- nonResponsiveAnswer:0, // 是否答非所问
113
- incorrectInfoAnswer:0, // 是否信息错误
114
- nonStandardFormatAnswer:0, // 是否信息不规范
115
- incompleteContentRetrieval:0, // 是否回答不完整
116
- unmatchedContentRetrieval:0, // 是否信息不匹配
117
- contextMisunderstandingQuery:0, //是否上下文理解错误
118
- feedbackText:"" //文字反馈
119
- };
120
- const feedbackLikeIcon = computed(() => {
121
- if (isFeedbackLikeClick.value) {
55
+ props: {
56
+ message: {
57
+ type: Object,
58
+ required: true,
59
+ default: function() {
60
+ return {} as IMessageModel;
61
+ }
62
+ }
63
+ },
64
+ setup(props, { emit }){
65
+ const isLikeIconHover = ref(false);
66
+ const isLikeIconClick = ref(false);
67
+ const isDislikeIconHover = ref(false);
68
+ const isDislikeIconClick = ref(false);
69
+ const isLikeSelectedDone = computed(() => {
70
+ try {
71
+ const jsonObj = JSON.parse(props.message.cloudCustomData);
72
+ return jsonObj.feedBackType === 1;
73
+ } catch (error) {
74
+ return false;
75
+ }
76
+ });
77
+ const isDislikeSelectedDone = computed(() => {
78
+ try {
79
+ const jsonObj = JSON.parse(props.message.cloudCustomData);
80
+ return jsonObj.feedBackType === 2;
81
+ } catch (error) {
82
+ return false;
83
+ }
84
+ });
85
+
86
+ const likeIcon = computed(() => {
87
+ if (isLikeSelectedDone.value) {
122
88
  return FeedbackLikeAfter;
123
- } else if (isFeedbackLikeHover.value) {
89
+ }
90
+ if (isLikeIconClick.value) {
91
+ return FeedbackLikeAfter;
92
+ } else if (isLikeIconHover.value) {
124
93
  return FeedbackLikeHover;
125
94
  } else {
126
95
  return FeedbackLikeBefore;
127
96
  }
128
97
  });
129
- const feedbackLikeClick = () => {
130
- isFeedbackLikeClick.value = !isFeedbackLikeClick.value;
131
- if(isFeedbackLikeClick.value){
132
- isFeedbackDislikeClick.value = false;
133
- feedbackReply.isSupport = 1;
98
+ const dislikeIcon = computed(() => {
99
+ if (isDislikeSelectedDone.value) {
100
+ return FeedbackDislikeAfter;
134
101
  }
135
- resetFeedback();
136
- }
137
- const feedbackDislikeIcon = computed(() => {
138
- if (isFeedbackDislikeClick.value) {
102
+
103
+ if (isDislikeIconClick.value) {
139
104
  return FeedbackDislikeAfter;
140
- } else if (isFeedbackDislikeHover.value) {
105
+ } else if (isDislikeIconHover.value) {
141
106
  return FeedbackDislikeHover;
142
107
  } else {
143
108
  return FeedbackDislikeBefore;
144
109
  }
145
110
  });
146
- const dialogButtonClick = (item) => {
147
- item.isSelected = !item.isSelected;
148
- }
149
- const feedbackDislikeClick = () => {
150
- isFeedbackDislikeClick.value = true;
151
- if(isFeedbackDislikeClick.value){
152
- isFeedbackLikeClick.value = false;
111
+ const isC2C = props.message.conversationType === TUIChatEngine.TYPES.CONV_C2C;
112
+ const messageInfo = {
113
+ msgSeq: props.message.sequence,
114
+ cloudCustomData: props.message.cloudCustomData,
115
+ // 网站渠道或测试窗
116
+ groupId: props.message.conversationType === TUIChatEngine.TYPES.CONV_GROUP ? props.message.to : null,
117
+ // uikit
118
+ // fromAccount: who sends the feedback, props.message.to : robot message recipient
119
+ fromAccount: isC2C ? props.message.to : null,
120
+ // toAccount: who receipts the feedback (customer service account)
121
+ toAccount: isC2C ? props.message.from : null,
122
+ msgRandom: isC2C ? props.message.random : null,
123
+ msgTime: isC2C ? props.message.time : null,
124
+ };
125
+ const onLikeIconClick = async () => {
126
+ // 已经选择了就不能再切换
127
+ if (isLikeSelectedDone.value || isLikeIconClick.value || isDislikeSelectedDone.value || isDislikeIconClick.value) {
128
+ return;
153
129
  }
130
+ isLikeIconClick.value = true;
131
+ emit('like', messageInfo);
154
132
  }
155
- const dislickClick = () => {
156
- showDialog.value = true;
157
- }
158
- const closeDialog = () => {
159
- isFeedbackDislikeClick.value = false;
160
- showDialog.value = false;
161
- resetFeedback();
162
- }
163
- const resetFeedback = () => {
164
- feedbackButton.value.forEach(item => {
165
- item.isSelected = false;
166
- });
167
- feedbackText.value = "";
168
- }
169
- const submitBadFeeback = () => {
170
- feedbackReply.isSupport = 0;
171
- feedbackButton.value.forEach(item => {
172
- feedbackReply[item.id] = item.isSelected ? 1 : 0;
173
- feedbackReply.feedbackText = feedbackText.value;
174
- });
133
+
134
+ const onDislikeIconClick = () => {
135
+ // 已经选择了就不能再切换
136
+ if (isLikeSelectedDone.value || isLikeIconClick.value || isDislikeSelectedDone.value || isDislikeIconClick.value) {
137
+ return;
138
+ }
139
+ isDislikeIconClick.value = true;
140
+ emit('dislike', messageInfo);
175
141
  }
176
142
 
177
143
  return {
178
- feedbackLikeIcon,
179
- isFeedbackLikeHover,
180
- feedbackLikeClick,
181
- isFeedbackDislikeHover,
182
- feedbackDislikeIcon,
183
- feedbackDislikeClick,
184
- GreenCheck,
185
- DialogCloseIcon,
186
- feedbackButton,
187
- showDialog,
188
- closeDialog,
189
- dislickClick,
190
- feedbackText,
191
- dialogButtonClick,
144
+ likeIcon,
145
+ isLikeIconHover,
146
+ onLikeIconClick,
147
+ isDislikeIconHover,
148
+ dislikeIcon,
149
+ onDislikeIconClick,
192
150
  TUITranslateService,
193
- submitBadFeeback
151
+ isPC,
152
+ isH5,
194
153
  };
195
154
  }
196
155
  }
@@ -201,9 +160,10 @@ export default {
201
160
  flex-direction: row !important;
202
161
  padding: 4px 10px;
203
162
  align-items: center;
204
- gap: 10px;
163
+ gap: 8px;
205
164
  border-radius: 8px;
206
165
  border: 1px solid var(---G61, #DBE1EB);
166
+ background-color: #fff;
207
167
  .feedback-like, .feedback-dislike {
208
168
  position: relative;
209
169
  display: flex;
@@ -220,124 +180,9 @@ export default {
220
180
  background-color: rgba(0,0,0,0.05);
221
181
  }
222
182
  }
223
- .feedback-dialog {
224
- position: fixed;
225
- top: 0;
226
- left: 0;
227
- right: 0;
228
- bottom: 0;
229
- background: rgba(13, 17, 26, 0.4);
230
- z-index: 1000;
231
- display: flex;
232
- justify-content: center;
233
- align-items: center;
234
- font-family: PingFangSC-Regular;
235
- &-main {
236
- width: 418px;
237
- min-height: 442px;
238
- background: white;
239
- border-radius: 16px;
240
- padding: 30px;
241
- overflow: hidden;
242
-
243
- .feedback-dialog-header {
244
- display: flex;
245
- justify-content: space-between;
246
- .dialog-header-content {
247
- display: flex;
248
- gap: 8px;
249
- align-items: center;
250
- .dialog-header-title {
251
- font-weight: 600;
252
-
253
- }
254
- }
255
- }
256
- }
257
- }
258
- .dialog-session-title {
259
- color: #4F586B;
260
- font-size: 14px;
183
+ .feedback-container-h5 {
184
+ background-color: rgba(255,255,255,0.75);
261
185
  }
262
- .dialog-select {
263
- margin-top: 30px;
264
- .dialog-button-list {
265
- display: flex;
266
- flex-wrap: wrap;
267
- justify-content: center;
268
- align-items: center;
269
- gap: 8px;
270
- margin-top: 10px;
271
- .dialog-button-row {
272
- flex: 0 0 49%;
273
- .dialog-button {
274
- border-radius: 8px;
275
- border: 1px solid #E4E8EE;
276
- background: #F9FAFC;
277
- padding: 10px 16px;
278
- display: flex;
279
- justify-content: center;
280
- font-size: 12px;
281
- color: #0f1014;
282
- cursor: pointer;
283
- text-align: center;
284
- align-items: center;
285
- &-selected {
286
- border-radius: 8px;
287
- border: 1px solid #1C66E5;
288
- background: rgba(28, 102, 229, 0.10);
289
- color: #0052d9;
290
- }
291
- }
292
- }
293
-
294
- }
295
- }
296
- .dialog-other {
297
- margin: 20px 0 10px 0;
298
- display: flex;
299
- flex-direction: column;
300
- gap: 10px;
301
- .dialog-other-input {
302
- border-radius: 12px;
303
- border: 1px solid #E4E8EE;
304
- background: #F9FAFC;
305
- height: 102px;
306
- padding: 10px 16px;
307
- display: flex;
308
- align-items: flex-start;
309
- align-self: stretch;
310
- resize: none;
311
- &::placeholder {
312
- color: #929CB2;
313
- font-size: 14px;
314
- }
315
- }
316
- }
317
- .dialog-foot {
318
- width: 100%;
319
- display: flex;
320
- margin-top: 30px;
321
- gap: 10px;
322
- justify-content: center;
323
- .dialog-submit {
324
- padding: 9px 33px;
325
- border-radius: 20px;
326
- background: #1C66E5;
327
- font-weight: 600;
328
- color: #fff;
329
- cursor: pointer;
330
- }
331
- .dialog-cancel {
332
- padding: 9px 33px;
333
- border-radius: 20px;
334
- border: 1px solid #1C66E5;
335
- font-weight: 600;
336
- color: #1C66E5;
337
- cursor: pointer;
338
- }
339
- }
340
-
341
186
  .tooltip {
342
187
  position: absolute;
343
188
  z-index: 100;
@@ -111,9 +111,18 @@
111
111
  :prevStatus="prevStatus"
112
112
  />
113
113
  </div>
114
- <!-- <div class="message-bubble-feedback-button">
115
- <FeedbackButton v-if="isFromRobot(message.cloudCustomData)"/>
116
- </div> -->
114
+ <div class="message-bubble-feedback-button">
115
+ <FeedbackButton
116
+ v-if="computedShowFeedback"
117
+ :message="message"
118
+ @like="onLike"
119
+ @dislike="onDislike"
120
+ />
121
+ <!-- 此模块为针对AI生成内容的说明。 -->
122
+ <div v-if="computedShowAINote" class="message-bubble-ai-note">
123
+ {{ TUITranslateService.t('AIDesk.该回复由AI生成,内容仅供参考') }}
124
+ </div>
125
+ </div>
117
126
  </main>
118
127
  </div>
119
128
  <!-- message extra area -->
@@ -142,10 +151,9 @@ import ReadStatus from './read-status/index.vue';
142
151
  import MessageQuote from './message-quote/index-web.vue';
143
152
  import Avatar from '../../../common/Avatar/index.vue';
144
153
  import loadingIcon from '../../../../assets/loading.png';
145
- import customerAvatar from '../../../../assets/customer_avatar.png';
146
- import { shallowCopyMessage } from '../../../../utils/utils';
154
+ import { canShowFeedback, shallowCopyMessage, canShowAINote } from '../../../../utils/utils';
147
155
  import { isPC,isH5 } from '../../../../utils/env';
148
- import { JSONToObject } from '../../../../utils/index';
156
+ import { JSONToObject, isWelcomeMessage } from '../../../../utils/index';
149
157
  import state from '../../../../utils/state.js';
150
158
  import { CUSTOM_MESSAGE_SRC } from '../../../../constant';
151
159
  import FeedbackButton from './feedback-button.vue';
@@ -158,6 +166,8 @@ interface IProps {
158
166
  classNameList?: string[];
159
167
  blinkMessageIDList?: string[];
160
168
  isAudioPlayed?: boolean | undefined;
169
+ enableFeedback: number;
170
+ enableAINote: number;
161
171
  }
162
172
 
163
173
  interface IEmits {
@@ -165,6 +175,8 @@ interface IEmits {
165
175
  (e: 'blinkMessage', messageID: string): void;
166
176
  // Only for uniapp
167
177
  (e: 'scrollTo', scrollHeight: number): void;
178
+ (e: 'like', messageInfo: Object): void;
179
+ (e: 'dislike', messageInfo: Object): void;
168
180
  }
169
181
 
170
182
  const emits = defineEmits<IEmits>();
@@ -175,6 +187,8 @@ const props = withDefaults(defineProps<IProps>(), {
175
187
  isAudioPlayed: false,
176
188
  blinkMessageIDList: () => [],
177
189
  classNameList: () => [],
190
+ enableFeedback: 0,
191
+ enableAINote: 1,
178
192
  });
179
193
 
180
194
  const TYPES = TUIChatEngine.TYPES;
@@ -230,6 +244,14 @@ const isMultiBranchMsg = computed(()=>{
230
244
  return false;
231
245
  });
232
246
 
247
+ const computedShowFeedback = computed(() => {
248
+ return props.enableFeedback === 1 && !isWelcomeMessage(message.value) && canShowFeedback(message.value.cloudCustomData);
249
+ });
250
+
251
+ const computedShowAINote = computed(() => {
252
+ return props.enableAINote === 1 && (state.get('currentLanguage') === 'zh' || state.get('currentLanguage') === 'en') && canShowAINote(message.value.cloudCustomData);
253
+ });
254
+
233
255
  function isFromRobot(cloudCustomData: string) {
234
256
  try {
235
257
  const jsonObj = JSONToObject(cloudCustomData);
@@ -241,22 +263,22 @@ function isFromRobot(cloudCustomData: string) {
241
263
 
242
264
  const avatarUrl = computed(() => {
243
265
  let url = '';
244
- if (message.value?.flow === 'in') {
245
- if (isFromRobot(message.value?.cloudCustomData)) {
246
- url = robotAvatar || customerAvatar;
266
+ if (message.value.flow === 'in') {
267
+ if (isFromRobot(message.value.cloudCustomData)) {
268
+ url = robotAvatar || message.value.avatar;
247
269
  } else {
248
- url = staffAvatar || message.value?.avatar;
270
+ url = staffAvatar || message.value.avatar;
249
271
  }
250
272
  } else {
251
- url = userAvatar || message.value?.avatar || '';
273
+ url = userAvatar || message.value.avatar || '';
252
274
  }
253
275
  return url;
254
276
  });
255
277
 
256
278
  const nickName = computed(() => {
257
279
  let nick = '';
258
- if (message.value?.flow === 'in') {
259
- if (isFromRobot(message.value?.cloudCustomData)) {
280
+ if (message.value.flow === 'in') {
281
+ if (isFromRobot(message.value.cloudCustomData)) {
260
282
  nick = robotNickName || props.content.showName;
261
283
  } else {
262
284
  nick = staffNickName || props.content.showName;
@@ -324,6 +346,13 @@ function scrollTo(scrollHeight: number) {
324
346
  function setStatus(status: ReadState) {
325
347
  prevStatus = status;
326
348
  }
349
+ function onLike(messageInfo: Object) {
350
+ emits('like', messageInfo);
351
+ }
352
+
353
+ function onDislike(messageInfo: Object) {
354
+ emits('dislike', messageInfo);
355
+ }
327
356
  </script>
328
357
 
329
358
  <style lang="scss" scoped>
@@ -382,7 +411,6 @@ function setStatus(status: ReadState) {
382
411
  }
383
412
 
384
413
  .message-body-nick-name {
385
- font-family: PingFangSC-Regular;
386
414
  display: block;
387
415
  margin-bottom: 4px;
388
416
  font-size: 12px;
@@ -447,7 +475,6 @@ function setStatus(status: ReadState) {
447
475
  .content-has-risk-tips {
448
476
  font-size: 12px;
449
477
  color: #fa5151;
450
- font-family: PingFangSC-Regular;
451
478
  margin-top: 5px;
452
479
  border-top: 1px solid #e5c7c7;
453
480
  padding-top: 5px;
@@ -525,7 +552,6 @@ function setStatus(status: ReadState) {
525
552
 
526
553
  .message-label {
527
554
  align-self: flex-end;
528
- font-family: PingFangSC-Regular;
529
555
  font-size: 12px;
530
556
  color: #b6b8ba;
531
557
  word-break: keep-all;
@@ -569,6 +595,7 @@ function setStatus(status: ReadState) {
569
595
  .message-bubble-feedback-button {
570
596
  display: flex;
571
597
  flex-direction: row;
598
+ gap: 8px;
572
599
  margin-top: 8px;
573
600
  }
574
601
  }
@@ -586,4 +613,12 @@ function setStatus(status: ReadState) {
586
613
  align-items: flex-end;
587
614
  }
588
615
  }
616
+ .message-bubble-ai-note {
617
+ color: #00000080;
618
+ align-self: center;
619
+ font-size: 12px;
620
+ font-weight: 400;
621
+ line-height: 22px;
622
+ flex: 0 0 auto;
623
+ }
589
624
  </style>
@@ -24,7 +24,6 @@ import {TUITranslateService} from "@tencentcloud/chat-uikit-engine";
24
24
  white-space: pre-wrap;
25
25
  font-size: 14px;
26
26
  text-size-adjust: none;
27
- font-family: PingFangSC-Regular;
28
27
  overflow-wrap: break-word;
29
28
  word-break: normal;
30
29
  }
@@ -33,7 +32,6 @@ import {TUITranslateService} from "@tencentcloud/chat-uikit-engine";
33
32
  white-space: pre-wrap;
34
33
  font-size: 14px;
35
34
  text-size-adjust: none;
36
- font-family: PingFangSC-Regular;
37
35
  overflow-wrap: break-word;
38
36
  word-break: normal;
39
37
  }
@@ -96,7 +96,6 @@ export default {
96
96
  line-height: 16px;
97
97
  width: -moz-fit-content;
98
98
  max-width: fit-content;
99
- font-family: PingFangSC-Regular;
100
99
  min-width: 50px;
101
100
  text-align: center;
102
101
  word-wrap: break-word;
@@ -85,7 +85,6 @@ export default {
85
85
  .card-title-container {
86
86
  padding: 8px 16px;
87
87
  border-radius: 0 10px 10px;
88
- font-family: PingFangSC-Regular;
89
88
  overflow-wrap: break-word;
90
89
  word-break: normal;
91
90
  max-width: fit-content;
@@ -107,7 +106,6 @@ export default {
107
106
  margin-top: 8px;
108
107
  cursor: pointer;
109
108
  line-height: 16px;
110
- font-family: PingFangSC-Regular;
111
109
  min-width: 50px;
112
110
  text-align: center;
113
111
  overflow-wrap: break-word;
@@ -75,7 +75,7 @@ import RadioMobile from './component-mobile/radios-mobile.vue';
75
75
  import LabelMobile from './component-mobile/label-mobile.vue';
76
76
  import FormPopup from './component-mobile/form-popup.vue';
77
77
  import { CUSTOM_MESSAGE_SRC } from '../../../../../../../constant';
78
- import {TUITranslateService} from '@tencentcloud/chat-uikit-engine';
78
+ import { TUITranslateService } from '@tencentcloud/chat-uikit-engine';
79
79
  const { ref, onMounted } = vue;
80
80
  interface Props {
81
81
  payload: customerServicePayloadType;
@@ -197,10 +197,6 @@ export default {
197
197
  <style lang="scss">
198
198
  @import "../styles/common.scss";
199
199
 
200
- .form-mobile-container {
201
- font-family: PingFangSC-Regular;
202
- }
203
-
204
200
  .edit-profile-container {
205
201
  @extend .container;
206
202
  font-size: 14px;
@@ -311,7 +307,6 @@ export default {
311
307
  display:flex;
312
308
  flex-direction: column;
313
309
  justify-content: center;
314
- font-family: PingFangSC-Regular;
315
310
  .form-button {
316
311
  display:flex;
317
312
  justify-content: center;
@@ -399,15 +394,16 @@ export default {
399
394
  .button-container {
400
395
  display: flex;
401
396
  justify-content: center;
402
- margin: 15px;
397
+ padding: 20px;
403
398
  .button {
404
399
  display: flex;
405
400
  justify-content: center;
406
- width: 87px;
407
- padding: 6px 10px;
401
+ width: 100%;
402
+ padding: 9px 33px;
408
403
  background-color: #1c66e5;
409
404
  color: white;
410
405
  border-radius: 20px;
406
+ font-weight: 500;
411
407
  }
412
408
  }
413
409
  </style>
@@ -151,7 +151,6 @@ export default {
151
151
  </script>
152
152
  <style lang="scss">
153
153
  .form-pc-container {
154
- font-family: PingFangSC-Regular;
155
154
  max-width: 350px;
156
155
  }
157
156
  .title-container {