@tencentcloud/ai-desk-customer-vue 1.5.6 → 1.5.9
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/CHANGELOG.md +18 -0
- package/assets/feedback_dislike_after.svg +1 -1
- package/assets/feedback_dislike_before.svg +2 -9
- package/assets/feedback_dislike_hover.svg +2 -9
- package/assets/feedback_like_after.svg +2 -13
- package/assets/feedback_like_before.svg +2 -9
- package/assets/feedback_like_hover.svg +2 -9
- package/components/CustomerServiceChat/chat-header/index-web.vue +19 -12
- package/components/CustomerServiceChat/feedback-modal/index.vue +391 -0
- package/components/CustomerServiceChat/index-web.vue +34 -1
- package/components/CustomerServiceChat/message-input/message-input-editor-web.vue +0 -1
- package/components/CustomerServiceChat/message-input/message-input-quote/index.vue +0 -3
- package/components/CustomerServiceChat/message-input-toolbar/index-web.vue +4 -2
- package/components/CustomerServiceChat/message-list/bottom-quick-order/index.vue +0 -1
- package/components/CustomerServiceChat/message-list/index-web.vue +92 -62
- package/components/CustomerServiceChat/message-list/message-elements/feedback-button.vue +96 -251
- package/components/CustomerServiceChat/message-list/message-elements/message-bubble-web.vue +51 -16
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-concurrency-limit.vue +0 -2
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-ivr-form/form-branch.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-branch/branch-pc.vue +0 -2
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-mobile.vue +34 -29
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-pc.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-order.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-product-card.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-rating/message-rating-star.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-stream.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-transfer-with-desc.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/styles/common.scss +0 -2
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-plugin-layout-web.vue +16 -0
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-plugin-web.vue +18 -0
- package/components/CustomerServiceChat/message-list/message-elements/message-quote/index-web.vue +0 -3
- package/components/CustomerServiceChat/message-list/message-elements/message-text.vue +26 -19
- package/components/CustomerServiceChat/message-list/message-elements/message-timestamp.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/read-status/index.vue +4 -2
- package/components/CustomerServiceChat/message-list/scroll-button/index.vue +8 -4
- package/components/CustomerServiceChat/message-list/style/web.scss +0 -2
- package/components/CustomerServiceChat/message-toolbar-button/index.vue +13 -9
- package/components/CustomerServiceChat/message-toolbar-button/toolbar-button-end-human-service.vue +1 -1
- package/components/CustomerServiceChat/style/common.scss +4 -0
- package/components/CustomerServiceChat/style/web.scss +2 -1
- package/components/common/BottomPopup/style/h5.scss +0 -1
- package/components/common/Dialog/style/color.scss +0 -1
- package/components/common/Toast/index-web.vue +1 -1
- package/constant.ts +3 -2
- package/locales/en/aidesk.ts +18 -15
- package/locales/fil/aidesk.ts +17 -15
- package/locales/id/aidesk.ts +17 -15
- package/locales/ja/aidesk.ts +17 -15
- package/locales/ms/aidesk.ts +17 -15
- package/locales/ru/aidesk.ts +17 -15
- package/locales/th/aidesk.ts +17 -15
- package/locales/vi/aidesk.ts +17 -15
- package/locales/zh_cn/aidesk.ts +17 -14
- package/locales/zh_tw/aidesk.ts +17 -15
- package/package.json +1 -1
- package/server.ts +5 -4
- package/utils/index.ts +6 -0
- package/utils/utils.ts +42 -0
- 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="
|
|
7
|
-
@mouseleave="
|
|
8
|
-
@click="
|
|
6
|
+
@mouseenter="isLikeIconHover = true"
|
|
7
|
+
@mouseleave="isLikeIconHover = false"
|
|
8
|
+
@click="onLikeIconClick"
|
|
9
9
|
>
|
|
10
|
-
<Icon :file="
|
|
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="
|
|
22
|
-
@mouseleave="
|
|
23
|
-
@click="
|
|
22
|
+
@mouseenter="isDislikeIconHover = true"
|
|
23
|
+
@mouseleave="isDislikeIconHover = false"
|
|
24
|
+
@click="onDislikeIconClick"
|
|
24
25
|
>
|
|
25
|
-
<Icon :file="
|
|
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
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
}
|
|
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
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
isFeedbackDislikeClick.value = false;
|
|
133
|
-
feedbackReply.isSupport = 1;
|
|
98
|
+
const dislikeIcon = computed(() => {
|
|
99
|
+
if (isDislikeSelectedDone.value) {
|
|
100
|
+
return FeedbackDislikeAfter;
|
|
134
101
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const feedbackDislikeIcon = computed(() => {
|
|
138
|
-
if (isFeedbackDislikeClick.value) {
|
|
102
|
+
|
|
103
|
+
if (isDislikeIconClick.value) {
|
|
139
104
|
return FeedbackDislikeAfter;
|
|
140
|
-
} else if (
|
|
105
|
+
} else if (isDislikeIconHover.value) {
|
|
141
106
|
return FeedbackDislikeHover;
|
|
142
107
|
} else {
|
|
143
108
|
return FeedbackDislikeBefore;
|
|
144
109
|
}
|
|
145
110
|
});
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
-
|
|
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:
|
|
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-
|
|
224
|
-
|
|
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
|
-
|
|
115
|
-
<FeedbackButton
|
|
116
|
-
|
|
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
|
|
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
|
|
245
|
-
if (isFromRobot(message.value
|
|
246
|
-
url = robotAvatar ||
|
|
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
|
|
270
|
+
url = staffAvatar || message.value.avatar;
|
|
249
271
|
}
|
|
250
272
|
} else {
|
|
251
|
-
url = userAvatar || message.value
|
|
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
|
|
259
|
-
if (isFromRobot(message.value
|
|
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
|
}
|
|
@@ -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;
|