@tencentcloud/ai-desk-customer-vue 1.3.0 → 1.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/CHANGELOG.md +23 -4
- package/assets/customer_avatar.png +0 -0
- package/assets/face.svg +10 -0
- package/assets/feedback_dialog_close.svg +3 -0
- package/assets/feedback_dislike_after.svg +3 -0
- package/assets/feedback_dislike_before.svg +10 -0
- package/assets/feedback_dislike_hover.svg +10 -0
- package/assets/feedback_like_after.svg +14 -0
- package/assets/feedback_like_before.svg +10 -0
- package/assets/feedback_like_hover.svg +10 -0
- package/assets/files.svg +5 -0
- package/assets/green_check.svg +4 -0
- package/assets/image.svg +8 -0
- package/assets/rating_tool_icon.svg +5 -0
- package/assets/rating_tool_icon_h5.svg +1 -0
- package/assets/video.svg +8 -0
- package/assets/video_h5.svg +1 -0
- package/components/CustomerServiceChat/chat-header/index-web.vue +16 -14
- package/components/CustomerServiceChat/index-web.vue +87 -13
- package/components/CustomerServiceChat/message-input/index-web.vue +31 -5
- package/components/CustomerServiceChat/message-input/message-input-editor-web.vue +25 -0
- package/components/CustomerServiceChat/message-input/message-input-quote/index.vue +29 -20
- package/components/CustomerServiceChat/message-input-toolbar/emoji-picker/emoji-picker-dialog.vue +36 -36
- package/components/CustomerServiceChat/message-input-toolbar/emoji-picker/index.vue +1 -1
- package/components/CustomerServiceChat/message-input-toolbar/file-upload/index.vue +6 -8
- package/components/CustomerServiceChat/message-input-toolbar/image-upload/index.vue +11 -16
- package/components/CustomerServiceChat/message-input-toolbar/index-web.vue +61 -18
- package/components/CustomerServiceChat/message-input-toolbar/rating-tool/index.vue +72 -0
- package/components/CustomerServiceChat/message-input-toolbar/toolbar-item-container/style/h5.scss +10 -1
- package/components/CustomerServiceChat/message-input-toolbar/user-define-input-tool.vue +80 -0
- package/components/CustomerServiceChat/message-input-toolbar/video-upload/index.vue +9 -14
- package/components/CustomerServiceChat/message-list/index-web.vue +38 -6
- package/components/CustomerServiceChat/message-list/message-elements/feedback-button.vue +369 -0
- package/components/CustomerServiceChat/message-list/message-elements/message-bubble-web.vue +81 -15
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/marked.ts +17 -10
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-branch.vue +18 -10
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-concurrency-limit.vue +1 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-desk.vue +13 -6
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-ivr-form/form-branch.vue +117 -0
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/{message-single-form → message-ivr-form}/form-input.vue +65 -111
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/{message-single-form → message-ivr-form}/index.vue +7 -2
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-branch/branch-pc.vue +25 -9
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-branch/index.vue +5 -3
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/component-mobile/input-mobile.vue +1 -0
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/component-mobile/label-mobile.vue +4 -2
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/component-pc/label-pc.vue +5 -3
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-mobile.vue +17 -5
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-pc.vue +21 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-order.vue +3 -3
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-product-card.vue +2 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-rating/message-rating-number.vue +9 -13
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-rating/message-rating-star.vue +11 -18
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-robot-welcome.vue +1 -0
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-stream.vue +14 -10
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-timeout-warning.vue +29 -0
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/styles/common.scss +1 -0
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-plugin-web.vue +22 -2
- package/components/CustomerServiceChat/message-list/message-elements/message-file.vue +1 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-quote/index-web.vue +6 -24
- package/components/CustomerServiceChat/message-list/message-elements/message-text.vue +0 -9
- package/components/CustomerServiceChat/message-list/message-elements/read-status/index.vue +31 -20
- package/components/CustomerServiceChat/message-list/message-elements/simple-message-list/index.vue +2 -1
- package/components/CustomerServiceChat/message-list/scroll-button/index.vue +3 -3
- package/components/CustomerServiceChat/message-list/style/web.scss +2 -1
- package/components/CustomerServiceChat/message-toolbar-button/index.vue +111 -42
- package/components/CustomerServiceChat/message-toolbar-button/toolbar-button-end-human-service.vue +59 -0
- package/components/CustomerServiceChat/message-toolbar-button/toolbar-button-human-service.vue +55 -0
- package/components/CustomerServiceChat/message-toolbar-button/toolbar-button-service-rating.vue +59 -0
- package/components/common/Toast/index-web.vue +4 -2
- package/constant.ts +25 -0
- package/interface.ts +35 -5
- package/locales/en/aidesk.ts +28 -15
- package/locales/fil/aidesk.ts +28 -15
- package/locales/id/aidesk.ts +28 -15
- package/locales/ja/aidesk.ts +28 -15
- package/locales/ms/aidesk.ts +28 -15
- package/locales/ru/aidesk.ts +28 -15
- package/locales/th/aidesk.ts +28 -15
- package/locales/vi/aidesk.ts +28 -15
- package/locales/zh_cn/aidesk.ts +28 -15
- package/locales/zh_tw/aidesk.ts +28 -15
- package/package.json +1 -1
- package/server.ts +5 -1
- package/utils/state.js +30 -0
- package/utils/utils.ts +48 -1
- package/assets/face.png +0 -0
- package/assets/files.png +0 -0
- package/assets/image.png +0 -0
- package/assets/video.png +0 -0
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-single-form/form-branch.vue +0 -68
|
@@ -12,21 +12,19 @@
|
|
|
12
12
|
:class="[message.flow === 'in' ? '' : 'reverse']"
|
|
13
13
|
>
|
|
14
14
|
<Avatar
|
|
15
|
-
|
|
15
|
+
v-if="showAvatar === 1"
|
|
16
16
|
useSkeletonAnimation
|
|
17
|
-
:url="
|
|
17
|
+
:url="avatarUrl"
|
|
18
18
|
/>
|
|
19
19
|
<main
|
|
20
20
|
:class="['message-body',message.flow==='out' && 'message-body-reverse']"
|
|
21
21
|
@click.stop
|
|
22
22
|
>
|
|
23
23
|
<div
|
|
24
|
-
v-if="
|
|
25
|
-
isPC
|
|
26
|
-
"
|
|
24
|
+
v-if="showNickName === 1"
|
|
27
25
|
class="message-body-nick-name"
|
|
28
26
|
>
|
|
29
|
-
{{
|
|
27
|
+
{{ nickName }}
|
|
30
28
|
</div>
|
|
31
29
|
<div
|
|
32
30
|
:class="[
|
|
@@ -109,8 +107,13 @@
|
|
|
109
107
|
<ReadStatus
|
|
110
108
|
class="message-label align-self-bottom"
|
|
111
109
|
:message="shallowCopyMessage(message)"
|
|
110
|
+
@setStatus="setStatus"
|
|
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
117
|
</main>
|
|
115
118
|
</div>
|
|
116
119
|
<!-- message extra area -->
|
|
@@ -142,7 +145,11 @@ import loadingIcon from '../../../../assets/loading.png';
|
|
|
142
145
|
import customerAvatar from '../../../../assets/customer_avatar.png';
|
|
143
146
|
import { shallowCopyMessage } from '../../../../utils/utils';
|
|
144
147
|
import { isPC,isH5 } from '../../../../utils/env';
|
|
148
|
+
import { JSONToObject } from '../../../../utils/index';
|
|
149
|
+
import state from '../../../../utils/state.js';
|
|
145
150
|
import { CUSTOM_MESSAGE_SRC } from '../../../../constant';
|
|
151
|
+
import FeedbackButton from './feedback-button.vue';
|
|
152
|
+
import { ReadState } from '../../../../constant';
|
|
146
153
|
const { computed, toRefs } = vue;
|
|
147
154
|
|
|
148
155
|
interface IProps {
|
|
@@ -182,7 +189,17 @@ const needLoadingIconMessageType = [
|
|
|
182
189
|
];
|
|
183
190
|
|
|
184
191
|
const { blinkMessageIDList, messageItem: message } = toRefs(props);
|
|
185
|
-
|
|
192
|
+
const {
|
|
193
|
+
showAvatar,
|
|
194
|
+
showNickName,
|
|
195
|
+
robotAvatar,
|
|
196
|
+
staffAvatar,
|
|
197
|
+
userAvatar,
|
|
198
|
+
robotNickName,
|
|
199
|
+
staffNickName,
|
|
200
|
+
userNickName,
|
|
201
|
+
} = state.get('avatarNickName');
|
|
202
|
+
let prevStatus = ReadState.Unread;
|
|
186
203
|
const isDisplayUnplayMark = computed<boolean>(() => {
|
|
187
204
|
return (
|
|
188
205
|
message.value.flow === 'in'
|
|
@@ -213,6 +230,43 @@ const isMultiBranchMsg = computed(()=>{
|
|
|
213
230
|
return false;
|
|
214
231
|
});
|
|
215
232
|
|
|
233
|
+
function isFromRobot(cloudCustomData: string) {
|
|
234
|
+
try {
|
|
235
|
+
const jsonObj = JSONToObject(cloudCustomData);
|
|
236
|
+
return jsonObj.hasOwnProperty("role") && jsonObj.role === "robot";
|
|
237
|
+
} catch (e) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const avatarUrl = computed(() => {
|
|
243
|
+
let url = '';
|
|
244
|
+
if (message.value?.flow === 'in') {
|
|
245
|
+
if (isFromRobot(message.value?.cloudCustomData)) {
|
|
246
|
+
url = robotAvatar || customerAvatar;
|
|
247
|
+
} else {
|
|
248
|
+
url = staffAvatar || message.value?.avatar;
|
|
249
|
+
}
|
|
250
|
+
} else {
|
|
251
|
+
url = userAvatar || message.value?.avatar || '';
|
|
252
|
+
}
|
|
253
|
+
return url;
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const nickName = computed(() => {
|
|
257
|
+
let nick = '';
|
|
258
|
+
if (message.value?.flow === 'in') {
|
|
259
|
+
if (isFromRobot(message.value?.cloudCustomData)) {
|
|
260
|
+
nick = robotNickName || props.content.showName;
|
|
261
|
+
} else {
|
|
262
|
+
nick = staffNickName || props.content.showName;
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
265
|
+
nick = userNickName || props.content.showName;
|
|
266
|
+
}
|
|
267
|
+
return nick;
|
|
268
|
+
});
|
|
269
|
+
|
|
216
270
|
const isProductCardOrOrderMessage = computed(() => {
|
|
217
271
|
if (message.value?.type == "TIMCustomElem") {
|
|
218
272
|
const src = JSON.parse(message.value.payload.data).src;
|
|
@@ -266,6 +320,10 @@ function blinkMessage(messageID: string) {
|
|
|
266
320
|
function scrollTo(scrollHeight: number) {
|
|
267
321
|
emits('scrollTo', scrollHeight);
|
|
268
322
|
}
|
|
323
|
+
|
|
324
|
+
function setStatus(status: ReadState) {
|
|
325
|
+
prevStatus = status;
|
|
326
|
+
}
|
|
269
327
|
</script>
|
|
270
328
|
|
|
271
329
|
<style lang="scss" scoped>
|
|
@@ -277,7 +335,7 @@ function scrollTo(scrollHeight: number) {
|
|
|
277
335
|
}
|
|
278
336
|
|
|
279
337
|
.message-bubble {
|
|
280
|
-
padding: 10px
|
|
338
|
+
padding: 10px 5px;
|
|
281
339
|
display: flex;
|
|
282
340
|
flex-direction: row;
|
|
283
341
|
user-select: none;
|
|
@@ -360,12 +418,12 @@ function scrollTo(scrollHeight: number) {
|
|
|
360
418
|
flex-direction: column;
|
|
361
419
|
min-width: 0;
|
|
362
420
|
box-sizing: border-box;
|
|
363
|
-
padding: 16px;
|
|
421
|
+
padding: 8px 16px;
|
|
364
422
|
font-size: 14px;
|
|
365
423
|
color: #000;
|
|
366
424
|
letter-spacing: 0;
|
|
367
|
-
|
|
368
|
-
word-break:
|
|
425
|
+
overflow-wrap: break-word;
|
|
426
|
+
word-break: normal;
|
|
369
427
|
position: relative;
|
|
370
428
|
|
|
371
429
|
.content-main {
|
|
@@ -398,7 +456,7 @@ function scrollTo(scrollHeight: number) {
|
|
|
398
456
|
|
|
399
457
|
.content-in {
|
|
400
458
|
background: #f3f4f7;
|
|
401
|
-
border-radius: 0
|
|
459
|
+
border-radius: 0 8px 8px;
|
|
402
460
|
}
|
|
403
461
|
|
|
404
462
|
.body-mobile {
|
|
@@ -407,7 +465,7 @@ function scrollTo(scrollHeight: number) {
|
|
|
407
465
|
|
|
408
466
|
.multi-branch-message {
|
|
409
467
|
background-color: transparent;
|
|
410
|
-
border-radius: 0
|
|
468
|
+
border-radius: 0 8px 8px;
|
|
411
469
|
padding: 0px;
|
|
412
470
|
}
|
|
413
471
|
|
|
@@ -422,7 +480,7 @@ function scrollTo(scrollHeight: number) {
|
|
|
422
480
|
.content-out {
|
|
423
481
|
background: linear-gradient(26deg, #1C66E5 2.07%, #03C8FD 152.75%);
|
|
424
482
|
color:#fff;
|
|
425
|
-
border-radius:
|
|
483
|
+
border-radius: 8px 0 8px 8px;
|
|
426
484
|
}
|
|
427
485
|
|
|
428
486
|
.content-no-padding {
|
|
@@ -454,7 +512,10 @@ function scrollTo(scrollHeight: number) {
|
|
|
454
512
|
.blink-content {
|
|
455
513
|
@keyframes reference-blink {
|
|
456
514
|
50% {
|
|
457
|
-
background-color
|
|
515
|
+
// 消息气泡的底色是渐变色,实际是 background-image,background-image 优先级高于 background-color
|
|
516
|
+
// 所以这里如果设置 background-color,动画将不会生效
|
|
517
|
+
// 闪烁时背景不渐变
|
|
518
|
+
background: linear-gradient(90deg, #ff9c19, #ff9c19);
|
|
458
519
|
}
|
|
459
520
|
}
|
|
460
521
|
|
|
@@ -504,6 +565,11 @@ function scrollTo(scrollHeight: number) {
|
|
|
504
565
|
align-self: flex-end;
|
|
505
566
|
}
|
|
506
567
|
}
|
|
568
|
+
.message-bubble-feedback-button {
|
|
569
|
+
display: flex;
|
|
570
|
+
flex-direction: row;
|
|
571
|
+
margin-top: 8px;
|
|
572
|
+
}
|
|
507
573
|
}
|
|
508
574
|
}
|
|
509
575
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {Marked} from 'marked';
|
|
2
|
+
import Log from '../../../../../../utils/logger';
|
|
2
3
|
|
|
3
4
|
export const marked = new Marked(
|
|
4
5
|
{mangle: false, headerIds: false},
|
|
@@ -7,19 +8,25 @@ export const marked = new Marked(
|
|
|
7
8
|
image(this: any, href: string | null, title: string | null, text: string) {
|
|
8
9
|
const safeHref = encodeURIComponent(href || '');
|
|
9
10
|
return `<div
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
class="image-container"
|
|
12
|
+
onclick="onMarkdownImageClicked('${safeHref}')"
|
|
13
|
+
style="cursor:pointer;" >
|
|
14
|
+
<img src="${href}" alt="${text}" onload="onMarkdownImageLoad()"/>
|
|
15
|
+
</div>
|
|
16
|
+
`;
|
|
16
17
|
},
|
|
17
18
|
link(this: any, href: string | null, title: string | null, text: string) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
if (href) {
|
|
20
|
+
// 匹配以 http:// 或 https:// 开头,所有 URL 主体字符,遇到第一个非主体字符(如中文括号、空格、表情符号等)时停止
|
|
21
|
+
let ret = href.replace(/https?:\/\/[\w\-./?=&:#]+(?=[^\w\-./?=&:#]|$)/g, (matchedUrl) => {
|
|
22
|
+
return `<a target="_blank" rel="noreferrer noopenner" class="message-marked_link" href="${matchedUrl || ''}" title="${title}">${matchedUrl}</a>`;
|
|
23
|
+
});
|
|
24
|
+
if (ret === href) {
|
|
25
|
+
Log.w(`Unable to extract url, href:${href}`);
|
|
26
|
+
}
|
|
27
|
+
return ret;
|
|
21
28
|
}
|
|
22
|
-
return
|
|
29
|
+
return text;
|
|
23
30
|
},
|
|
24
31
|
},
|
|
25
32
|
},
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
:class="['branch-body',isPC ? 'branch-bubble':'branch-bubble-h5']"
|
|
6
6
|
>
|
|
7
7
|
<Icon :src="iconQuestion" class="branch-title-icon"/>
|
|
8
|
-
|
|
8
|
+
<div class="branch-title-text">
|
|
9
|
+
{{ content.header || content.title }}
|
|
10
|
+
</div>
|
|
9
11
|
</div>
|
|
10
12
|
<div
|
|
11
13
|
v-for="(item, index) in content.items"
|
|
@@ -91,14 +93,15 @@ export default {
|
|
|
91
93
|
display: flex;
|
|
92
94
|
min-width: 0;
|
|
93
95
|
box-sizing: border-box;
|
|
94
|
-
padding:
|
|
96
|
+
padding: 8px 16px;
|
|
95
97
|
font-size: 14px;
|
|
96
98
|
color: #000;
|
|
97
99
|
letter-spacing: 0;
|
|
98
|
-
|
|
99
|
-
word-break:
|
|
100
|
+
overflow-wrap: break-word;
|
|
101
|
+
word-break: normal;
|
|
100
102
|
position: relative;
|
|
101
|
-
|
|
103
|
+
width: 100%;
|
|
104
|
+
max-width: fit-content;
|
|
102
105
|
.branch-main {
|
|
103
106
|
box-sizing: border-box;
|
|
104
107
|
display: flex;
|
|
@@ -122,8 +125,9 @@ export default {
|
|
|
122
125
|
margin-bottom: 8px;
|
|
123
126
|
}
|
|
124
127
|
.branch-item {
|
|
125
|
-
color
|
|
128
|
+
color: #1c66e5;
|
|
126
129
|
cursor: pointer;
|
|
130
|
+
display: inline-block;
|
|
127
131
|
}
|
|
128
132
|
.warning-item {
|
|
129
133
|
color: #ff9800;
|
|
@@ -131,18 +135,22 @@ export default {
|
|
|
131
135
|
.branch-card {
|
|
132
136
|
min-width: 250px;
|
|
133
137
|
max-width: 350px;
|
|
134
|
-
display:flex;
|
|
135
|
-
flex-direction:column;
|
|
138
|
+
display: flex;
|
|
139
|
+
flex-direction: column;
|
|
136
140
|
align-items: flex-start;
|
|
137
141
|
}
|
|
138
142
|
.branch-item-selected {
|
|
139
|
-
cursor:
|
|
143
|
+
cursor: default;
|
|
140
144
|
color: #a0a7b8;
|
|
141
|
-
opacity:0.6;
|
|
145
|
+
opacity: 0.6;
|
|
142
146
|
}
|
|
143
147
|
.branch-title-icon {
|
|
144
148
|
margin-right: 5px;
|
|
145
149
|
align-items: flex-start !important;
|
|
146
150
|
margin-top: 2px;
|
|
147
151
|
}
|
|
152
|
+
.branch-title-text {
|
|
153
|
+
display: inline-block;
|
|
154
|
+
min-width: 0;
|
|
155
|
+
}
|
|
148
156
|
</style>
|
|
@@ -79,9 +79,10 @@ import { CustomMessagePayload, TextMessagePayload, customerServicePayloadType }
|
|
|
79
79
|
import MessageRating from './message-rating/index.vue';
|
|
80
80
|
import vue from '../../../../../../adapter-vue';
|
|
81
81
|
import { JSONToObject } from '../../../../../../utils/index';
|
|
82
|
+
import { isEnabledMessageReadReceiptGlobal } from '../../../../../../utils/utils';
|
|
82
83
|
import { CUSTOM_MESSAGE_SRC } from '../../../../../../constant';
|
|
83
84
|
import MessageBranch from './message-branch.vue';
|
|
84
|
-
import MessageForm from './message-
|
|
85
|
+
import MessageForm from './message-ivr-form/index.vue';
|
|
85
86
|
import MessageIMRobotWelcome from './message-robot-welcome.vue';
|
|
86
87
|
import MessageProductCard from './message-product-card.vue';
|
|
87
88
|
import MessageRichText from './message-rich-text.vue';
|
|
@@ -118,16 +119,22 @@ export default {
|
|
|
118
119
|
default: () => ({}),
|
|
119
120
|
},
|
|
120
121
|
},
|
|
121
|
-
emits: ['showFormPopup', 'heightChanged'],
|
|
122
|
+
emits: ['showFormPopup', 'heightChanged', 'messageSent'],
|
|
122
123
|
setup(props: Props, { emit }) {
|
|
123
124
|
const payload = computed<customerServicePayloadType>(() => {
|
|
124
125
|
return props.message && JSONToObject(props.message?.payload?.data);
|
|
125
126
|
});
|
|
126
|
-
const sendTextMessage = (payload: TextMessagePayload) => {
|
|
127
|
-
TUIChatService.sendTextMessage({
|
|
127
|
+
const sendTextMessage = async (payload: TextMessagePayload, cloudCustomData?: string) => {
|
|
128
|
+
await TUIChatService.sendTextMessage({
|
|
129
|
+
payload,
|
|
130
|
+
cloudCustomData: cloudCustomData || '',
|
|
131
|
+
needReadReceipt: isEnabledMessageReadReceiptGlobal()
|
|
132
|
+
});
|
|
133
|
+
emit('messageSent');
|
|
128
134
|
};
|
|
129
|
-
const sendCustomMessage = (payload: CustomMessagePayload) => {
|
|
130
|
-
TUIChatService.sendCustomMessage({payload});
|
|
135
|
+
const sendCustomMessage = async (payload: CustomMessagePayload) => {
|
|
136
|
+
await TUIChatService.sendCustomMessage({ payload });
|
|
137
|
+
emit('messageSent');
|
|
131
138
|
};
|
|
132
139
|
const handleShowFormPopup = (data: boolean) => {
|
|
133
140
|
emit('showFormPopup', data);
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="form-branch-container">
|
|
3
|
+
<p
|
|
4
|
+
v-if="props.title"
|
|
5
|
+
class="form-card-title"
|
|
6
|
+
>
|
|
7
|
+
{{ props.title }}
|
|
8
|
+
</p>
|
|
9
|
+
<div
|
|
10
|
+
v-for="(item, index) in props.list"
|
|
11
|
+
:key="index"
|
|
12
|
+
:class="getItemClass(item)"
|
|
13
|
+
@click="listItemClick(item)"
|
|
14
|
+
>
|
|
15
|
+
{{ item.content }}
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script lang="ts">
|
|
21
|
+
import vue from '../../../../../../../adapter-vue';
|
|
22
|
+
const { computed, ref } = vue;
|
|
23
|
+
|
|
24
|
+
interface branchItem {
|
|
25
|
+
content: string;
|
|
26
|
+
desc: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface Props {
|
|
30
|
+
title: string;
|
|
31
|
+
list: branchItem[];
|
|
32
|
+
selectedContent: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default {
|
|
36
|
+
props: {
|
|
37
|
+
title: {
|
|
38
|
+
type: String,
|
|
39
|
+
default: '',
|
|
40
|
+
},
|
|
41
|
+
list: {
|
|
42
|
+
type: Array,
|
|
43
|
+
default: () => [],
|
|
44
|
+
},
|
|
45
|
+
selectedContent: {
|
|
46
|
+
type: String,
|
|
47
|
+
default: '',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
emits: ['input-click'],
|
|
51
|
+
setup(props: Props, { emit }) {
|
|
52
|
+
const disabled = ref<boolean>(false);
|
|
53
|
+
const selectedItem = ref<string>('');
|
|
54
|
+
const listItemClick = (branch: branchItem): void => {
|
|
55
|
+
if (disabled.value || props.selectedContent) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
emit('input-click', branch);
|
|
59
|
+
disabled.value = true;
|
|
60
|
+
selectedItem.value = branch.content;
|
|
61
|
+
};
|
|
62
|
+
const getItemClass = (item: branchItem) => {
|
|
63
|
+
const classes:string[] = [];
|
|
64
|
+
if (props.selectedContent) {
|
|
65
|
+
classes.push(item.content === props.selectedContent ? 'item-selected' : 'item-disabled');
|
|
66
|
+
} else if (disabled.value) {
|
|
67
|
+
classes.push(item.content === selectedItem.value ? 'item-selected' : 'item-disabled');
|
|
68
|
+
}
|
|
69
|
+
classes.push('ivr-form-branch-item');
|
|
70
|
+
return classes;
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
props,
|
|
74
|
+
listItemClick,
|
|
75
|
+
disabled,
|
|
76
|
+
selectedItem,
|
|
77
|
+
getItemClass
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
</script>
|
|
82
|
+
<style lang="scss">
|
|
83
|
+
.form-branch-container {
|
|
84
|
+
.form-card-title {
|
|
85
|
+
margin-bottom: 8px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.ivr-form-branch-item {
|
|
89
|
+
cursor: pointer;
|
|
90
|
+
color: #1C66E5;
|
|
91
|
+
background-color: #fff;
|
|
92
|
+
border: 1px solid rgba(0, 110, 255, 0.3);
|
|
93
|
+
padding: 12px;
|
|
94
|
+
border-radius: 20px;
|
|
95
|
+
margin-top: 8px;
|
|
96
|
+
line-height: 16px;
|
|
97
|
+
width: -moz-fit-content;
|
|
98
|
+
max-width: fit-content;
|
|
99
|
+
font-family: PingFangSC-Regular;
|
|
100
|
+
min-width: 50px;
|
|
101
|
+
text-align: center;
|
|
102
|
+
word-wrap: break-word;
|
|
103
|
+
}
|
|
104
|
+
.item-disabled {
|
|
105
|
+
cursor: default !important;
|
|
106
|
+
opacity: 0.6;
|
|
107
|
+
color: #94BFFF;
|
|
108
|
+
background-color: #F5F9FF;
|
|
109
|
+
border: 1px solid rgba(0, 110, 255, 0.15);
|
|
110
|
+
}
|
|
111
|
+
.item-selected {
|
|
112
|
+
background-color: rgba(54, 141, 255, 0.15) !important;
|
|
113
|
+
position: relative;
|
|
114
|
+
cursor: default !important;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
</style>
|