@tencentcloud/ai-desk-customer-vue 1.6.6 → 1.6.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.
- package/CHANGELOG.md +18 -0
- package/components/CustomerServiceChat/customer-queue-page/index.vue +7 -16
- package/components/CustomerServiceChat/index-web.vue +16 -4
- package/components/CustomerServiceChat/message-input/message-input-editor-web.vue +1 -1
- package/components/CustomerServiceChat/message-input-toolbar/rating-tool/index.vue +1 -1
- package/components/CustomerServiceChat/message-list/index-web.vue +1 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-stream.vue +4 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-thinking.vue +1 -1
- package/components/CustomerServiceChat/message-list/message-elements/simple-message-list/index.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-tool/index-web.vue +35 -0
- package/components/CustomerServiceChat/message-toolbar-button/index.vue +2 -2
- package/constant.ts +2 -1
- package/interface.ts +5 -0
- package/locales/en/aidesk.ts +1 -1
- package/locales/index.ts +2 -0
- package/locales/ko/TUIChat.ts +163 -0
- package/locales/ko/aidesk.ts +43 -0
- package/locales/ko/component.ts +6 -0
- package/locales/ko/index.ts +26 -0
- package/locales/ko/time.ts +37 -0
- package/package.json +2 -7
- package/server.ts +12 -2
- package/utils/utils.ts +32 -2
- package/assets/video-play.png +0 -0
- package/components/CustomerServiceChat/message-list/message-elements/video-play.vue +0 -59
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
## 1.6.8 @2026.1.7
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
- 新增参数 messageToolDisplayConfig,支持控制消息工具的显隐。
|
|
5
|
+
- 多语言新增韩语。
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- 修复引用订单消息的显示。
|
|
9
|
+
|
|
10
|
+
## 1.6.7 @2025.12.30
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
- initWithProfile 接口 Options 新增参数 clientCustomData,支持用户登录时传入自定义字段。
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- 优化关闭排队页面的用户体验。
|
|
17
|
+
- H5 端已知问题。
|
|
18
|
+
|
|
1
19
|
## 1.6.6 @2025.12.22
|
|
2
20
|
|
|
3
21
|
### Features
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
</div>
|
|
16
16
|
</div>
|
|
17
17
|
<div class="customer-queue-end-button">
|
|
18
|
-
<div :class="['customer-queue-end-button-content', isClicked ? 'button-clicked' : '']" @click="
|
|
18
|
+
<div :class="['customer-queue-end-button-content', isClicked ? 'button-clicked' : '']" @click="leaveQueue">
|
|
19
19
|
{{ TUITranslateService.t("AIDesk.结束排队") }}
|
|
20
20
|
</div>
|
|
21
21
|
</div>
|
|
@@ -24,9 +24,8 @@
|
|
|
24
24
|
<script lang="ts" setup>
|
|
25
25
|
import vue from '../../../adapter-vue';
|
|
26
26
|
const { ref, onMounted, onUnmounted } = vue;
|
|
27
|
-
import { IConversationModel, StoreName,
|
|
28
|
-
import {
|
|
29
|
-
import { getTo, isEnabledMessageReadReceiptGlobal } from '../../../utils/utils';
|
|
27
|
+
import { IConversationModel, StoreName, TUIStore, TUITranslateService } from '@tencentcloud/chat-uikit-engine';
|
|
28
|
+
import { getTo, leaveQueuing } from '../../../utils/utils';
|
|
30
29
|
const currentConversation = ref<IConversationModel>();
|
|
31
30
|
const isClicked = ref(false);
|
|
32
31
|
const props = defineProps({
|
|
@@ -35,6 +34,7 @@ const props = defineProps({
|
|
|
35
34
|
default: 0
|
|
36
35
|
},
|
|
37
36
|
});
|
|
37
|
+
const emits = defineEmits(['closeQueuePage']);
|
|
38
38
|
onMounted(() => {
|
|
39
39
|
TUIStore.watch(StoreName.CONV, {
|
|
40
40
|
currentConversation: onCurrentConversationUpdate,
|
|
@@ -51,22 +51,13 @@ const onCurrentConversationUpdate = (conversation: IConversationModel) => {
|
|
|
51
51
|
currentConversation.value = conversation;
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
-
const
|
|
54
|
+
const leaveQueue = () => {
|
|
55
55
|
if (isClicked.value) {
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
58
|
isClicked.value = true;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
conversationType: currentConversation.value.type,
|
|
62
|
-
payload: {
|
|
63
|
-
data: JSON.stringify({
|
|
64
|
-
customerServicePlugin: 0,
|
|
65
|
-
src: CUSTOM_MESSAGE_SRC.USER_END_CONVERSATION,
|
|
66
|
-
}),
|
|
67
|
-
},
|
|
68
|
-
needReadReceipt: isEnabledMessageReadReceiptGlobal(),
|
|
69
|
-
},{ onlineUserOnly:true });
|
|
59
|
+
leaveQueuing(getTo(currentConversation.value));
|
|
60
|
+
emits('closeQueuePage');
|
|
70
61
|
}
|
|
71
62
|
</script>
|
|
72
63
|
<style lang="scss">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="['tui-chat', !isPC && 'tui-chat-h5']" :key="currentLanguage">
|
|
3
3
|
<div
|
|
4
|
-
v-if="currentConversationID && (!props.showQueuePage || queueNumber < 0 || queueNumber === undefined)"
|
|
4
|
+
v-if="currentConversationID && (!props.showQueuePage || queueNumber < 0 || queueNumber === undefined || hasLeftQueue)"
|
|
5
5
|
:class="['tui-chat', !isPC && 'tui-chat-h5']"
|
|
6
6
|
>
|
|
7
7
|
<ChatHeader
|
|
@@ -94,8 +94,8 @@
|
|
|
94
94
|
@close="() => { showFeedbackModal = false }"
|
|
95
95
|
/>
|
|
96
96
|
</div>
|
|
97
|
-
<div v-if="props.showQueuePage && queueNumber >= 0" :class="['tui-chat', !isPC && 'tui-chat-h5']">
|
|
98
|
-
<CustomerQueuePage :queueNumber="queueNumber"/>
|
|
97
|
+
<div v-if="props.showQueuePage && queueNumber >= 0 && !hasLeftQueue" :class="['tui-chat', !isPC && 'tui-chat-h5']">
|
|
98
|
+
<CustomerQueuePage :queueNumber="queueNumber" @closeQueuePage="closeQueuePage"/>
|
|
99
99
|
</div>
|
|
100
100
|
</div>
|
|
101
101
|
</template>
|
|
@@ -116,7 +116,7 @@ import MessageInput from './message-input/index-web.vue';
|
|
|
116
116
|
import MessageInputToolbar from './message-input-toolbar/index-web.vue';
|
|
117
117
|
import EmojiDialog from './message-input-toolbar/emoji-dialog-mobile/emoji-dialog-mobile.vue';
|
|
118
118
|
import { isH5, isPC } from '../../utils/env';
|
|
119
|
-
import { ToolbarButtonModel, ToolbarDisplayType, InputToolbarModel, QuickOrderModel, IHeaderConfig} from '../../interface';
|
|
119
|
+
import { ToolbarButtonModel, ToolbarDisplayType, InputToolbarModel, QuickOrderModel, IHeaderConfig, IMessageToolDisplayConfig } from '../../interface';
|
|
120
120
|
import Log from '../../utils/logger';
|
|
121
121
|
import MessageToolbarButton from './message-toolbar-button/index.vue';
|
|
122
122
|
import TUILocales from '../../locales';
|
|
@@ -158,6 +158,7 @@ interface IProps {
|
|
|
158
158
|
enableSendingAudio?: number;
|
|
159
159
|
showQueuePage?: number;
|
|
160
160
|
showAllRobotWelcomeItems?: number;
|
|
161
|
+
messageToolDisplayConfig?: IMessageToolDisplayConfig[];
|
|
161
162
|
}
|
|
162
163
|
|
|
163
164
|
const emits = defineEmits(['closeChat']);
|
|
@@ -178,6 +179,7 @@ const languageForShowList = ref<Array<string>>([]);
|
|
|
178
179
|
const feedbackModalRef = ref();
|
|
179
180
|
const showFeedbackModal = ref(false);
|
|
180
181
|
const queueNumber = ref(-1);
|
|
182
|
+
const hasLeftQueue = ref(false);
|
|
181
183
|
let timezone = '';
|
|
182
184
|
let countryID = '';
|
|
183
185
|
const props = withDefaults(defineProps<IProps>(), {
|
|
@@ -326,6 +328,10 @@ const setShowAllRobotWelcomeItems = () => {
|
|
|
326
328
|
state.set('showAllRobotWelcomeItems', props.showAllRobotWelcomeItems);
|
|
327
329
|
}
|
|
328
330
|
|
|
331
|
+
const setMessageToolDisplayConfig = () => {
|
|
332
|
+
state.set('messageToolDisplayConfig', props.messageToolDisplayConfig || []);
|
|
333
|
+
}
|
|
334
|
+
|
|
329
335
|
try {
|
|
330
336
|
const userContext = TUILogin.getContext();
|
|
331
337
|
if (userContext.userID == '' && props.SDKAppID !==0 && props.userID !=='' && props.userSig !==''){
|
|
@@ -341,6 +347,7 @@ try {
|
|
|
341
347
|
setEnableURLDetection();
|
|
342
348
|
setShowAllRobotWelcomeItems();
|
|
343
349
|
getTimeZoneAndCountry();
|
|
350
|
+
setMessageToolDisplayConfig();
|
|
344
351
|
if (isNonEmptyObject(props.bottomQuickOrder)) {
|
|
345
352
|
showBottomQuickOrder.value = true;
|
|
346
353
|
}
|
|
@@ -528,8 +535,13 @@ function onDislike(messageInfo: Object) {
|
|
|
528
535
|
function onIsQueuingUpdate(data: {conversationID: string, value: number}) {
|
|
529
536
|
if (data && data.conversationID === currentConversationID.value) {
|
|
530
537
|
queueNumber.value = data.value;
|
|
538
|
+
hasLeftQueue.value = false;
|
|
531
539
|
}
|
|
532
540
|
}
|
|
541
|
+
|
|
542
|
+
function closeQueuePage() {
|
|
543
|
+
hasLeftQueue.value = true;
|
|
544
|
+
}
|
|
533
545
|
</script>
|
|
534
546
|
|
|
535
547
|
<style scoped lang="scss" src="./style/index.scss">
|
|
@@ -361,7 +361,7 @@ function handlePasteText(e: ClipboardEvent) {
|
|
|
361
361
|
const text = e.clipboardData?.getData('text/plain') || '';
|
|
362
362
|
// if paste html in pc, paste by tiptap editor default
|
|
363
363
|
// if paste text in pc or mobile, parse text to html to render emoji
|
|
364
|
-
if (!html) {
|
|
364
|
+
if (isH5 || !html) {
|
|
365
365
|
const renderArray = parseTextToRenderArray(text);
|
|
366
366
|
insertEditorContent(renderArray);
|
|
367
367
|
}
|
|
@@ -24,7 +24,7 @@ import ratingToolIcon from '../../../../assets/rating_tool_icon.svg'
|
|
|
24
24
|
import ratingToolIconH5 from '../../../../assets/rating_tool_icon_h5.svg';
|
|
25
25
|
import { getTo } from '../../../../utils/utils';
|
|
26
26
|
import { CUSTOM_MESSAGE_SRC } from '../../../../constant';
|
|
27
|
-
const { ref
|
|
27
|
+
const { ref } = vue;
|
|
28
28
|
|
|
29
29
|
const props = defineProps({
|
|
30
30
|
isH5ToolShow:{
|
|
@@ -208,7 +208,6 @@ import {
|
|
|
208
208
|
getBoundingClientRect,
|
|
209
209
|
getScrollInfo,
|
|
210
210
|
} from '@tencentcloud/universal-api';
|
|
211
|
-
import { throttle } from 'lodash';
|
|
212
211
|
import MessageText from './message-elements/message-text.vue';
|
|
213
212
|
import MessageImage from './message-elements/message-image-web.vue';
|
|
214
213
|
import MessageAudio from './message-elements/message-audio-web.vue';
|
|
@@ -237,6 +236,7 @@ import {
|
|
|
237
236
|
deepCopy,
|
|
238
237
|
isNonEmptyObject,
|
|
239
238
|
updateCustomStore,
|
|
239
|
+
throttle
|
|
240
240
|
} from '../../../utils/utils';
|
|
241
241
|
import { isMessageInvisible, isThinkingMessage, isThinkingMessageOverTime, JSONToObject, isTransferMessageWithoutDesc } from '../../../utils/index';
|
|
242
242
|
import { isCustomerConversation } from '../../../index';
|
|
@@ -45,7 +45,7 @@ const displayedContent = computed(() => {
|
|
|
45
45
|
imageSrc.value = decodeURIComponent(href);
|
|
46
46
|
}
|
|
47
47
|
// @ts-ignore
|
|
48
|
-
window.
|
|
48
|
+
window.onMarkdownMediaLoad = function() {
|
|
49
49
|
// empty implementation
|
|
50
50
|
// 已经用 ResizeObserver 观测高度,这里不用重复通知高度变化
|
|
51
51
|
}
|
|
@@ -85,6 +85,9 @@ watch(() => props.payload, (newValue: string, oldValue: string) => {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
const _payloadObject = JSONToObject(props.payload);
|
|
88
|
+
if (!_payloadObject.chunks) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
88
91
|
chunks.value = Array.isArray(_payloadObject.chunks) ? _payloadObject.chunks.join('') : _payloadObject.chunks;
|
|
89
92
|
isFinished.value = _payloadObject.isFinished === 1;
|
|
90
93
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import vue from '../../../../adapter-vue';
|
|
12
12
|
import Icon from '../../../common/Icon.vue';
|
|
13
13
|
import loading_message from '../../../../assets/loading_message.svg';
|
|
14
|
-
const { ref,
|
|
14
|
+
const { ref, onMounted, onUnmounted} = vue;
|
|
15
15
|
export default {
|
|
16
16
|
components:{
|
|
17
17
|
Icon
|
package/components/CustomerServiceChat/message-list/message-elements/simple-message-list/index.vue
CHANGED
|
@@ -158,7 +158,6 @@ import TUIChatEngine, {
|
|
|
158
158
|
TUITranslateService,
|
|
159
159
|
} from '@tencentcloud/chat-uikit-engine';
|
|
160
160
|
import addIcon from '../../../../../assets/back.svg';
|
|
161
|
-
import playIcon from '../../../../../assets/video-play.png';
|
|
162
161
|
import Icon from '../../../../common/Icon.vue';
|
|
163
162
|
import MessageContainer from './message-container.vue';
|
|
164
163
|
import MessageRecord from '../message-record/index.vue';
|
|
@@ -46,6 +46,7 @@ import downloadIcon from '../../../../assets/download.svg'
|
|
|
46
46
|
import { enableSampleTaskStatus } from '../../../../utils/enableSampleTaskStatus';
|
|
47
47
|
import { transformTextWithKeysToEmojiNames } from '../../emoji-config';
|
|
48
48
|
import { isH5, isPC, isUniFrameWork } from '../../../../utils/env';
|
|
49
|
+
import state from '../../../../utils/state.js';
|
|
49
50
|
|
|
50
51
|
// uni-app conditional compilation will not run the following code
|
|
51
52
|
// #ifndef APP || APP-PLUS || MP || H5
|
|
@@ -62,6 +63,16 @@ const props = withDefaults(defineProps<IProps>(), {
|
|
|
62
63
|
|
|
63
64
|
const TYPES = TUIChatEngine.TYPES;
|
|
64
65
|
|
|
66
|
+
const messageToolDisplayConfig = state.get('messageToolDisplayConfig') || [];
|
|
67
|
+
|
|
68
|
+
const getMessageToolDisplayConfig = (key: string) => {
|
|
69
|
+
if (!messageToolDisplayConfig || messageToolDisplayConfig.length === 0) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
const item = messageToolDisplayConfig.find(item => item.key === key);
|
|
73
|
+
return item ? item.display : undefined;
|
|
74
|
+
}
|
|
75
|
+
|
|
65
76
|
const actionItems = ref([
|
|
66
77
|
{
|
|
67
78
|
key: 'open',
|
|
@@ -69,6 +80,10 @@ const actionItems = ref([
|
|
|
69
80
|
iconUrl: copyIcon,
|
|
70
81
|
renderCondition() {
|
|
71
82
|
if (!message.value) return false;
|
|
83
|
+
const config = getMessageToolDisplayConfig('open');
|
|
84
|
+
if (config === false) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
72
87
|
return (
|
|
73
88
|
isPC
|
|
74
89
|
&& (message.value?.type === TYPES.MSG_FILE
|
|
@@ -84,6 +99,10 @@ const actionItems = ref([
|
|
|
84
99
|
iconUrl: copyIcon,
|
|
85
100
|
renderCondition() {
|
|
86
101
|
if (!message.value) return false;
|
|
102
|
+
const config = getMessageToolDisplayConfig('copy');
|
|
103
|
+
if (config === false) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
87
106
|
return message.value.type === TYPES.MSG_TEXT;
|
|
88
107
|
},
|
|
89
108
|
clickEvent: copyMessage,
|
|
@@ -94,6 +113,10 @@ const actionItems = ref([
|
|
|
94
113
|
iconUrl: revokeIcon,
|
|
95
114
|
renderCondition() {
|
|
96
115
|
if (!message.value) return false;
|
|
116
|
+
const config = getMessageToolDisplayConfig('revoke');
|
|
117
|
+
if (config === false) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
97
120
|
return message.value.flow === 'out' && message.value.status === 'success';
|
|
98
121
|
},
|
|
99
122
|
clickEvent: revokeMessage,
|
|
@@ -104,6 +127,10 @@ const actionItems = ref([
|
|
|
104
127
|
iconUrl: delIcon,
|
|
105
128
|
renderCondition() {
|
|
106
129
|
if (!message.value) return false;
|
|
130
|
+
const config = getMessageToolDisplayConfig('delete');
|
|
131
|
+
if (config === false) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
107
134
|
return message.value.status === 'success';
|
|
108
135
|
},
|
|
109
136
|
clickEvent: deleteMessage,
|
|
@@ -114,6 +141,10 @@ const actionItems = ref([
|
|
|
114
141
|
iconUrl: quoteIcon,
|
|
115
142
|
renderCondition() {
|
|
116
143
|
if (!message.value) return false;
|
|
144
|
+
const config = getMessageToolDisplayConfig('quote');
|
|
145
|
+
if (config === false) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
117
148
|
const _message = TUIStore.getMessageModel(message.value.ID);
|
|
118
149
|
return message.value.status === 'success' && !_message.getSignalingInfo();
|
|
119
150
|
},
|
|
@@ -124,6 +155,10 @@ const actionItems = ref([
|
|
|
124
155
|
iconUrl: downloadIcon,
|
|
125
156
|
renderCondition(){
|
|
126
157
|
if (!message.value) return false;
|
|
158
|
+
const config = getMessageToolDisplayConfig('download');
|
|
159
|
+
if (config === false) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
127
162
|
return message.value.type === TYPES.MSG_FILE && message.value.flow === 'out';
|
|
128
163
|
},
|
|
129
164
|
clickEvent:downloadMessage,
|
|
@@ -44,7 +44,7 @@ import { isH5 } from '../../../utils/env';
|
|
|
44
44
|
import { ToolbarButtonModel } from '../../../interface';
|
|
45
45
|
import Icon from '../../common/Icon.vue';
|
|
46
46
|
import { TOOLBAR_BUTTON_TYPE } from '../../../constant';
|
|
47
|
-
import { isEnabledMessageReadReceiptGlobal, openSafeUrl, getTo, isNonEmptyObject, transferToTaskFlow, transferToHuman, debounce,
|
|
47
|
+
import { isEnabledMessageReadReceiptGlobal, openSafeUrl, getTo, isNonEmptyObject, transferToTaskFlow, transferToHuman, debounce, leaveQueuing } from '../../../utils/utils';
|
|
48
48
|
import ToolbarButtonHumanService from './toolbar-button-human-service.vue';
|
|
49
49
|
import ToolbarButtonServiceRating from './toolbar-button-service-rating.vue';
|
|
50
50
|
import ToolbarButtonEndHumanService from './toolbar-button-end-human-service.vue';
|
|
@@ -190,7 +190,7 @@ const onClick = debounce((item:ToolbarButtonModel, index: number) => {
|
|
|
190
190
|
} else if (item.type === 4 && isNonEmptyObject(item.content)) {
|
|
191
191
|
transferToHuman(getTo(currentConversation.value), item.content.groupID, item.content.specificMemberList, item.content.description);
|
|
192
192
|
} else if (item.type === 5 && queueNumber.value >= 0) {
|
|
193
|
-
|
|
193
|
+
leaveQueuing(getTo(currentConversation.value));
|
|
194
194
|
} else if (props.toolbarButtonList !== undefined && typeof props.toolbarButtonList[index].clickEvent === 'function') {
|
|
195
195
|
props.toolbarButtonList[index].clickEvent();
|
|
196
196
|
}
|
package/constant.ts
CHANGED
|
@@ -184,5 +184,6 @@ export const SUPPORTED_LANGUAGES = {
|
|
|
184
184
|
vi: {name: 'Tiếng Việt', codeForShow: 'Vi'},
|
|
185
185
|
zh: {name: '中文简体', codeForShow: 'Zh'},
|
|
186
186
|
zh_tw: {name: '中文繁體', codeForShow: 'Zh-TW'},
|
|
187
|
-
ru: {name:'Русский', codeForShow: 'Ru'}
|
|
187
|
+
ru: {name:'Русский', codeForShow: 'Ru'},
|
|
188
|
+
ko: {name: '한국어', codeForShow: 'Ko'},
|
|
188
189
|
}
|
package/interface.ts
CHANGED
package/locales/en/aidesk.ts
CHANGED
|
@@ -38,6 +38,6 @@ const AIDesk = {
|
|
|
38
38
|
"排队等待中": "In Queue",
|
|
39
39
|
"排队等待话术": "We apologize for the wait. All agents are currently assisting other customers. You will be connected shortly. Thank you for your patience.",
|
|
40
40
|
"当前前方排队人数": "Queue Position",
|
|
41
|
-
"结束排队": "
|
|
41
|
+
"结束排队": "Leave Queue"
|
|
42
42
|
}
|
|
43
43
|
export default AIDesk;
|
package/locales/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import vi from './vi';
|
|
|
9
9
|
import ms from './ms';
|
|
10
10
|
import th from './th';
|
|
11
11
|
import ru from './ru';
|
|
12
|
+
import ko from './ko';
|
|
12
13
|
|
|
13
14
|
export interface ILanguageResources {
|
|
14
15
|
[key: string]: string | ILanguageResources;
|
|
@@ -25,6 +26,7 @@ const messages: Record<string, ILanguageResources> = {
|
|
|
25
26
|
...ms,
|
|
26
27
|
...th,
|
|
27
28
|
...ru,
|
|
29
|
+
...ko,
|
|
28
30
|
};
|
|
29
31
|
|
|
30
32
|
export default messages;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
const TUIChat = {
|
|
2
|
+
"按Enter发送,Ctrl+Enter换行": "Enter 키로 전송, Ctrl+Enter로 줄바꿈",
|
|
3
|
+
"表情": "[이모티콘]",
|
|
4
|
+
"查看更多": "더보기",
|
|
5
|
+
"撤回": "메시지 철회",
|
|
6
|
+
"撤回了一条消息": "님이 메시지를 철회했습니다",
|
|
7
|
+
"打开": "열기",
|
|
8
|
+
"单击下载": "클릭하여 다운로드",
|
|
9
|
+
"下载": "다운로드",
|
|
10
|
+
"点此投诉": "신고하기",
|
|
11
|
+
"点击处理": "처리하기",
|
|
12
|
+
"对方正在输入": "입력 중...",
|
|
13
|
+
"发起群视频": "그룹 영상통화 시작",
|
|
14
|
+
"发起群语音": "그룹 음성통화 시작",
|
|
15
|
+
"发起通话": "통화 시작",
|
|
16
|
+
"发送失败": "전송 실패",
|
|
17
|
+
"复制": "복사",
|
|
18
|
+
"复制成功": "클립보드에 복사됨",
|
|
19
|
+
"该消息不存在": "해당 메시지가 존재하지 않습니다",
|
|
20
|
+
"关闭阅读状态": "읽음 상태 끄기",
|
|
21
|
+
"管理员开启全员禁言": "관리자가 전체 음소거를 설정했습니다",
|
|
22
|
+
"欢迎使用TUICallKit": "TUICallKit에 오신 것을 환영합니다",
|
|
23
|
+
"回复": "답장",
|
|
24
|
+
"回复详情": "답글",
|
|
25
|
+
"集成TUICallKit": "TUICallKit 연동",
|
|
26
|
+
"检测到您暂未集成TUICallKit,无法体验音视频通话功能": "TUICallKit이 연동되어 있지 않아 음성/영상 통화를 이용할 수 없습니다.",
|
|
27
|
+
"结束群聊": "그룹 통화 편집",
|
|
28
|
+
"进行体验": "체험하기",
|
|
29
|
+
"经度": "경도",
|
|
30
|
+
"拒绝": "거절",
|
|
31
|
+
"拒绝通话": "통화 거절",
|
|
32
|
+
"开通腾讯实时音视频服务": "Tencent 실시간 음영상 서비스 연동",
|
|
33
|
+
"聊天记录": "[채팅 기록]",
|
|
34
|
+
"描述": "설명",
|
|
35
|
+
"内容包含敏感词汇": "내용에 민감한 단어가 포함되어 있습니다",
|
|
36
|
+
"您": "회원님",
|
|
37
|
+
"您当前购买使用的套餐包暂未开通此功能": "구매하신 요금제에서는 이 기능을 지원하지 않습니다.",
|
|
38
|
+
"您当前购买使用的套餐包暂未开通群消息已读回执功能": "구매하신 요금제에서는 그룹 메시지 읽음 확인 기능을 지원하지 않습니다.",
|
|
39
|
+
"您当前购买使用的套餐包暂未开通在线用户列表功能": "구매하신 요금제에서는 온라인 사용자 목록 기능을 지원하지 않습니다.",
|
|
40
|
+
"您已被管理员禁言": "관리자에 의해 음소거되었습니다",
|
|
41
|
+
"您有": "있습니다",
|
|
42
|
+
"请点击": "클릭",
|
|
43
|
+
"请输入消息": "메시지를 입력해 주세요",
|
|
44
|
+
"取消": "취소",
|
|
45
|
+
"取消通话": "통화 취소",
|
|
46
|
+
"全部已读": "모두 읽음",
|
|
47
|
+
"确定": "확인",
|
|
48
|
+
"确认重发该消息?": "해당 메시지를 재전송하시겠습니까?",
|
|
49
|
+
"人关闭阅读状态": "읽음 상태 비활성화",
|
|
50
|
+
"人未读": "읽지 않음",
|
|
51
|
+
"人已读": "읽음",
|
|
52
|
+
"删除": "삭제",
|
|
53
|
+
"涉及敏感内容": "민감한 내용 포함",
|
|
54
|
+
"申请加入": "가입 신청",
|
|
55
|
+
"视频": "[비디오]",
|
|
56
|
+
"视频通话": "영상통화",
|
|
57
|
+
"条回复": "답글",
|
|
58
|
+
"条入群申请": "그룹 가입 신청",
|
|
59
|
+
"条新消息": "개 새 메시지",
|
|
60
|
+
"通话时长": "통화 시간",
|
|
61
|
+
"同意": "동의",
|
|
62
|
+
"图片": "[이미지]",
|
|
63
|
+
"图片消息失败,无效的图片格式": "이미지 전송 실패: 유효하지 않은 이미지 형식입니다.",
|
|
64
|
+
"纬度": "위도",
|
|
65
|
+
"未读": "읽지 않음",
|
|
66
|
+
"位置": "[위치]",
|
|
67
|
+
"文件": "[파일]",
|
|
68
|
+
"文件不存在,请检查文件路径是否正确": "파일이 존재하지 않습니다. 파일 경로가 올바른지 확인해 주세요.",
|
|
69
|
+
"文件大小超出了限制,如果上传文件,最大限制是100MB": "파일 크기가 제한을 초과했습니다. 파일 업로드 시 최대 허용 크기는 100MB입니다.",
|
|
70
|
+
"文件消息失败,禁止发送违规封禁的文件": "파일 전송 실패: 금지된 파일은 전송할 수 없습니다.",
|
|
71
|
+
"我": "나",
|
|
72
|
+
"无法查看": "볼 수 없음",
|
|
73
|
+
"无法定位到原消息": "원본 메시지로 이동할 수 없습니다",
|
|
74
|
+
"无法收听": "재생할 수 없음",
|
|
75
|
+
"正在加载": "로딩 중...",
|
|
76
|
+
"加载结束": "로딩 완료",
|
|
77
|
+
"无应答": "응답 없음",
|
|
78
|
+
"系统消息": "시스템 메시지",
|
|
79
|
+
"消息": "[메시지]",
|
|
80
|
+
"消息或者资料中文本存在敏感内容,发送失败": "메시지 또는 프로필 텍스트에 민감한 내용이 포함되어 전송에 실패했습니다.",
|
|
81
|
+
"消息详情": "메시지 상세 내용",
|
|
82
|
+
"消息长度超出限制,消息长度不要超过12K": "메시지 길이가 제한을 초과했습니다. 메시지는 12K를 초과할 수 없습니다.",
|
|
83
|
+
"消息中图片存在敏感内容,发送失败": "메시지의 이미지에 민감한 내용이 포함되어 전송에 실패했습니다.",
|
|
84
|
+
"选择提醒的人": "멘션할 사람 선택",
|
|
85
|
+
"已读": "읽음",
|
|
86
|
+
"已过撤回时限": "철회 가능 시간이 지났습니다",
|
|
87
|
+
"已接听": "응답됨",
|
|
88
|
+
"已拒绝": "거부됨",
|
|
89
|
+
"已同意": "승인됨",
|
|
90
|
+
"引用": "답장",
|
|
91
|
+
"引用失败": "답장 실패",
|
|
92
|
+
"语音": "[음성]",
|
|
93
|
+
"语音通话": "음성통화",
|
|
94
|
+
"重新编辑": "다시 편집",
|
|
95
|
+
"重新发送": "재전송",
|
|
96
|
+
"转发": "전달",
|
|
97
|
+
"翻译": "번역",
|
|
98
|
+
"转文字": "텍스트로 변환",
|
|
99
|
+
"隐藏": "숨김",
|
|
100
|
+
"转发给": "에게 전달",
|
|
101
|
+
"自定义": "[커스텀 메시지]",
|
|
102
|
+
"自定义消息": "커스텀 메시지",
|
|
103
|
+
"腾讯云 IM": "텐센트 클라우드 채팅",
|
|
104
|
+
"空": "없음",
|
|
105
|
+
"文本包含本地审核拦截词": "텍스트에 로컬 차단 단어가 포함되어 있습니다",
|
|
106
|
+
"按住说话": "길게 눌러 말하기",
|
|
107
|
+
"松开发送": "손을 떼어 전송",
|
|
108
|
+
"松手取消": "손을 떼어 취소",
|
|
109
|
+
"录音结束提醒": "녹음 종료까지 ",
|
|
110
|
+
"语音播放失败": "음성 재생 실패",
|
|
111
|
+
"请检查麦克风访问权限": "마이크 접근 권한을 확인해 주세요",
|
|
112
|
+
"按压时间过短,请按压超过1秒": "녹음 시간이 너무 짧습니다. 1초 이상 길게 녹음해 주세요",
|
|
113
|
+
"正在录音": "녹음 중",
|
|
114
|
+
"继续上滑可取消": "계속 위로 밀면 취소됩니다",
|
|
115
|
+
"松开手指 取消发送": "손을 떼어 전송 취소",
|
|
116
|
+
"此机型暂不支持复制功能": "이 기종에서는 복사 기능을 지원하지 않습니다",
|
|
117
|
+
"请开通翻译功能": "번역 기능을 활성화해 주세요",
|
|
118
|
+
"请开通语音转文字功能": "음성→텍스트 기능을 활성화해 주세요",
|
|
119
|
+
"翻译中": "번역 중",
|
|
120
|
+
"转换中": "변환 중",
|
|
121
|
+
"由IM提供翻译支持": "IM에서 번역을 지원합니다",
|
|
122
|
+
"所有人": "모두",
|
|
123
|
+
"已达到表情回应上限数量": "이모티콘 반응 최대 수에 도달했습니다",
|
|
124
|
+
"等": "등",
|
|
125
|
+
"人": "명",
|
|
126
|
+
"返回": "돌아가기",
|
|
127
|
+
"关闭": "닫기",
|
|
128
|
+
"多选": "다중 선택",
|
|
129
|
+
"合并转发": "묶음 전달",
|
|
130
|
+
"逐条转发": "개별 전달",
|
|
131
|
+
"未选择消息": "선택된 메시지가 없습니다",
|
|
132
|
+
"[草稿]": "[초안]",
|
|
133
|
+
"[消息]": "[메시지]",
|
|
134
|
+
"[文本]": "[텍스트]",
|
|
135
|
+
"[自定义消息]": "[커스텀 메시지]",
|
|
136
|
+
"[图片]": "[이미지]",
|
|
137
|
+
"[音频]": "[오디오]",
|
|
138
|
+
"[语音]": "[음성]",
|
|
139
|
+
"[视频]": "[비디오]",
|
|
140
|
+
"[文件]": "[파일]",
|
|
141
|
+
"[位置]": "[위치]",
|
|
142
|
+
"[地理位置]": "[위치]",
|
|
143
|
+
"[动画表情]": "[이모티콘]",
|
|
144
|
+
"[群提示]": "[그룹 알림]",
|
|
145
|
+
"[群提示消息]": "[그룹 알림]",
|
|
146
|
+
"[聊天记录]": "[채팅 기록]",
|
|
147
|
+
"[机器人自定义消息]": "[봇 커스텀 메시지]",
|
|
148
|
+
"引用内容已撤回": "답장한 메시지가 철회되었습니다",
|
|
149
|
+
"群聊的聊天记录": "그룹 채팅 기록",
|
|
150
|
+
"和": " 및 ",
|
|
151
|
+
"的聊天记录": "의 채팅 기록",
|
|
152
|
+
"请升级IMSDK到v2.10.1或更高版本查看此消息": "해당 메시지를 보려면 IMSDK를 v2.10.1 이상으로 업데이트해 주세요",
|
|
153
|
+
"该群聊已被解散": "해당 그룹이 해산되었습니다",
|
|
154
|
+
"您已被管理员移出群聊": "관리자가 회원님을 그룹에서 제거했습니다",
|
|
155
|
+
"您已退出该群聊": "그룹을 탈퇴했습니다",
|
|
156
|
+
"您已被禁止聊天": "채팅 금지되었습니다",
|
|
157
|
+
"账号被强制下线": "계정이 강제로 로그아웃되었습니다",
|
|
158
|
+
"登录失败": "로그인 실패",
|
|
159
|
+
"链接": "[링크]",
|
|
160
|
+
"回到最新位置": "",
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export default TUIChat;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const AIDesk = {
|
|
2
|
+
"结束人工会话": "대화 종료",
|
|
3
|
+
"转人工服务": "상담사 연결",
|
|
4
|
+
"跳转": "열기",
|
|
5
|
+
"立即填写": "지금 작성하기",
|
|
6
|
+
"已提交": "제출됨",
|
|
7
|
+
"提交": "제출",
|
|
8
|
+
"查看内容": "내용 보기",
|
|
9
|
+
"请填写必填项": "필수 항목을 작성해 주세요.",
|
|
10
|
+
"请输入内容": "내용을 입력해 주세요.",
|
|
11
|
+
"如果满意请给好评哦~": "서비스에 대해 평가해 주세요.",
|
|
12
|
+
"请对本次服务进行评价": "이번 서비스에 대해 평가해 주세요.",
|
|
13
|
+
"提交评价": "평가 제출",
|
|
14
|
+
"并发限制": "현재 접속자가 많아 서비스 이용이 지연되고 있습니다. 잠시 후 다시 시도해 주세요.",
|
|
15
|
+
"分支选项异常": "옵션에 문제가 있습니다. 설정을 확인해 주세요.",
|
|
16
|
+
"服务评价": "서비스 평가",
|
|
17
|
+
"满意": "만족",
|
|
18
|
+
"不满意": "불만족",
|
|
19
|
+
"感谢您的反馈,我们会持续优化改进": "피드백 감사합니다. 지속적으로 개선하겠습니다.",
|
|
20
|
+
"您遇到了哪方面的问题": "어떤 문제가 발생했나요?",
|
|
21
|
+
"其他反馈内容": "기타 의견",
|
|
22
|
+
"取消": "취소",
|
|
23
|
+
"答非所问": "질문과 무관한 답변",
|
|
24
|
+
"未匹配相关内容": "관련 없는 내용",
|
|
25
|
+
"信息错误": "정보 오류",
|
|
26
|
+
"上下文理解错误": "문맥 이해 오류",
|
|
27
|
+
"格式不规范": "올바르지 않은 형식",
|
|
28
|
+
"内容不完整": "불완전한 내용",
|
|
29
|
+
"file 大小超过 100MB,无法发送": "파일 크기가 100MB를 초과하여 전송할 수 없습니다.",
|
|
30
|
+
"image 大小超过 20MB,无法发送": "이미지 크기가 20MB를 초과하여 전송할 수 없습니다.",
|
|
31
|
+
"video 大小超过 100MB,无法发送": "동영상 크기가 100MB를 초과하여 전송할 수 없습니다.",
|
|
32
|
+
"提交成功": "제출 완료",
|
|
33
|
+
"userID 只能包含可打印 ASCII 字符": "userID에는 인쇄 가능한 ASCII 문자만 사용할 수 있습니다.",
|
|
34
|
+
"userID 不能包含'administrator'": "userID에는 'administrator' 문자열을 포함할 수 없습니다.",
|
|
35
|
+
"userID 长度不能超过45字节": "userID 길이는 45바이트를 초과할 수 없습니다.",
|
|
36
|
+
"我们想知道你对此回答不满意的原因,你认为更好的回答是什么?": "해당 답변에 만족하지 않으신 이유와 더 나은 답변이 무엇인지 알려주세요.",
|
|
37
|
+
"该回复由AI生成,内容仅供参考": "해당 답변은 AI가 생성한 내용으로 참고용입니다.",
|
|
38
|
+
"排队等待中": "대기 중",
|
|
39
|
+
"排队等待话术": "현재 모든 상담원이 상담 중입니다. 곧 연결해 드리겠습니다. 기다려 주셔서 감사합니다.",
|
|
40
|
+
"当前前方排队人数": "현재 대기 인원",
|
|
41
|
+
"结束排队": "대기 취소"
|
|
42
|
+
}
|
|
43
|
+
export default AIDesk;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import TUIChat from './TUIChat';
|
|
2
|
+
import Component from './component';
|
|
3
|
+
import time from './time';
|
|
4
|
+
import AIDesk from './aidesk';
|
|
5
|
+
|
|
6
|
+
const messages = {
|
|
7
|
+
ko: {
|
|
8
|
+
"取消": '취소',
|
|
9
|
+
"确定": '확인',
|
|
10
|
+
"发送": '보내기',
|
|
11
|
+
"系统通知": '시스템 알림',
|
|
12
|
+
"关闭": '닫기',
|
|
13
|
+
"图片": '사진',
|
|
14
|
+
"文件": '파일',
|
|
15
|
+
"表情": '이모티콘',
|
|
16
|
+
"视频": '동영상',
|
|
17
|
+
"录制": '녹음',
|
|
18
|
+
"拍照": '사진 찍기',
|
|
19
|
+
AIDesk,
|
|
20
|
+
TUIChat,
|
|
21
|
+
Component,
|
|
22
|
+
time,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default messages;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const time = {
|
|
2
|
+
"周": "주",
|
|
3
|
+
"天": "일",
|
|
4
|
+
"小时": "시간",
|
|
5
|
+
"分钟": "분",
|
|
6
|
+
"刚刚": "방금",
|
|
7
|
+
"前": "전",
|
|
8
|
+
"昨天": "어제",
|
|
9
|
+
"星期一": "월요일",
|
|
10
|
+
"星期二": "화요일",
|
|
11
|
+
"星期三": "수요일",
|
|
12
|
+
"星期四": "목요일",
|
|
13
|
+
"星期五": "금요일",
|
|
14
|
+
"星期六": "토요일",
|
|
15
|
+
"星期日": "일요일",
|
|
16
|
+
"一月": "1월",
|
|
17
|
+
"二月": "2월",
|
|
18
|
+
"三月": "3월",
|
|
19
|
+
"四月": "4월",
|
|
20
|
+
"五月": "5월",
|
|
21
|
+
"六月": "6월",
|
|
22
|
+
"七月": "7월",
|
|
23
|
+
"八月": "8월",
|
|
24
|
+
"九月": "9월",
|
|
25
|
+
"十月": "10월",
|
|
26
|
+
"十一月": "11월",
|
|
27
|
+
"十二月": "12월",
|
|
28
|
+
"一": "월",
|
|
29
|
+
"二": "화",
|
|
30
|
+
"三": "수",
|
|
31
|
+
"四": "목",
|
|
32
|
+
"五": "금",
|
|
33
|
+
"六": "토",
|
|
34
|
+
"日": "일",
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default time;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tencentcloud/ai-desk-customer-vue",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.8",
|
|
4
4
|
"description": "Vue2/Vue3 UIKit for AI Desk",
|
|
5
5
|
"main": "index",
|
|
6
6
|
"keywords": [
|
|
@@ -31,14 +31,9 @@
|
|
|
31
31
|
"@tiptap/extension-text": "2.0.0-beta.220",
|
|
32
32
|
"@tiptap/pm": "2.0.0-beta.220",
|
|
33
33
|
"@tiptap/suggestion": "2.0.0-beta.220",
|
|
34
|
-
"@types/lodash": "^4.14.202",
|
|
35
34
|
"countries-and-timezones": "^3.8.0",
|
|
36
|
-
"dayjs": "^1.11.10",
|
|
37
35
|
"js-audio-recorder": "^1.0.7",
|
|
38
|
-
"
|
|
39
|
-
"marked": "^6.0.0",
|
|
40
|
-
"mp-html": "^2.5.0",
|
|
41
|
-
"vue-clipboard3": "2.0.0"
|
|
36
|
+
"marked": "^6.0.0"
|
|
42
37
|
},
|
|
43
38
|
"publishConfig": {
|
|
44
39
|
"access": "public",
|
package/server.ts
CHANGED
|
@@ -29,6 +29,7 @@ interface IInitWithProfile {
|
|
|
29
29
|
nickName?: string,
|
|
30
30
|
avatar?: string,
|
|
31
31
|
customerServiceID?: string,
|
|
32
|
+
clientCustomData?: string,
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
interface IProfile {
|
|
@@ -45,6 +46,7 @@ export default class TUICustomerServer {
|
|
|
45
46
|
private myProfile: IProfile;
|
|
46
47
|
private paramsForActiveAgain: any;
|
|
47
48
|
private loginFailToasts: any[];
|
|
49
|
+
private clientCustomData: string;
|
|
48
50
|
constructor() {
|
|
49
51
|
TUICore.registerService(TUIConstants.TUICustomerServicePlugin.SERVICE.NAME, this);
|
|
50
52
|
TUICore.registerExtension(TUIConstants.TUIContact.EXTENSION.CONTACT_LIST.EXT_ID, this);
|
|
@@ -54,6 +56,7 @@ export default class TUICustomerServer {
|
|
|
54
56
|
this.isLoggedIn = false;
|
|
55
57
|
this.loggedInUserID = '';
|
|
56
58
|
this.myProfile = {};
|
|
59
|
+
this.clientCustomData = '';
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
static getInstance(): TUICustomerServer {
|
|
@@ -138,7 +141,7 @@ export default class TUICustomerServer {
|
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
public async initWithProfile(options: IInitWithProfile) {
|
|
141
|
-
const { SDKAppID, userID, userSig, nickName, avatar, customerServiceID } = options;
|
|
144
|
+
const { SDKAppID, userID, userSig, nickName, avatar, customerServiceID, clientCustomData } = options;
|
|
142
145
|
Log.l(`TUICustomerServer.initWithProfile version:${version}`);
|
|
143
146
|
if (nickName) {
|
|
144
147
|
// chat 个人资料的昵称是 nick
|
|
@@ -155,6 +158,12 @@ export default class TUICustomerServer {
|
|
|
155
158
|
this.customerServiceIDList.push(this.currentCustomerServiceID);
|
|
156
159
|
}
|
|
157
160
|
}
|
|
161
|
+
|
|
162
|
+
if (clientCustomData) {
|
|
163
|
+
this.clientCustomData = clientCustomData;
|
|
164
|
+
} else {
|
|
165
|
+
this.clientCustomData = '';
|
|
166
|
+
}
|
|
158
167
|
return this.init(SDKAppID, userID, userSig);
|
|
159
168
|
}
|
|
160
169
|
|
|
@@ -276,7 +285,7 @@ export default class TUICustomerServer {
|
|
|
276
285
|
|
|
277
286
|
// 激活会话服务流
|
|
278
287
|
private activeServiceFlow(params: any) {
|
|
279
|
-
Log.i(`TUICustomerServer.activeServiceFlow params: language:${params.robotLang} country:${params.country} timezone:${params.timezone}`);
|
|
288
|
+
Log.i(`TUICustomerServer.activeServiceFlow params: language:${params.robotLang} country:${params.country} timezone:${params.timezone} clientCustomData:${this.clientCustomData}`);
|
|
280
289
|
this.paramsForActiveAgain = { ...params };
|
|
281
290
|
TUIChatService.sendCustomMessage({
|
|
282
291
|
to: params.conversationID.slice(3),
|
|
@@ -289,6 +298,7 @@ export default class TUICustomerServer {
|
|
|
289
298
|
language: params.robotLang,
|
|
290
299
|
country: params.country,
|
|
291
300
|
timezone: params.timezone,
|
|
301
|
+
clientCustomData: this.clientCustomData,
|
|
292
302
|
}
|
|
293
303
|
}),
|
|
294
304
|
},
|
package/utils/utils.ts
CHANGED
|
@@ -236,6 +236,8 @@ export function getQuoteContentForDesk(message: IMessageModel): string {
|
|
|
236
236
|
result = payload.content.tip;
|
|
237
237
|
} else if (src === CUSTOM_MESSAGE_SRC.ROBOT_MSG) {
|
|
238
238
|
result = payload.content.title;
|
|
239
|
+
} else if (src === CUSTOM_MESSAGE_SRC.PRODUCT_CARD) {
|
|
240
|
+
result = payload.content.header || payload.content.desc;
|
|
239
241
|
}
|
|
240
242
|
}
|
|
241
243
|
|
|
@@ -378,7 +380,7 @@ export function debounce(func, delay) {
|
|
|
378
380
|
}
|
|
379
381
|
}
|
|
380
382
|
|
|
381
|
-
export function
|
|
383
|
+
export function leaveQueuing(conversationID: string) {
|
|
382
384
|
TUIChatService.sendCustomMessage({
|
|
383
385
|
to: conversationID,
|
|
384
386
|
conversationType: TUIChatEngine.TYPES.CONV_C2C,
|
|
@@ -390,4 +392,32 @@ export function endQueuing(conversationID: string) {
|
|
|
390
392
|
},
|
|
391
393
|
needReadReceipt: isEnabledMessageReadReceiptGlobal(),
|
|
392
394
|
},{ onlineUserOnly: true });
|
|
393
|
-
};
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
export function throttle(
|
|
398
|
+
func,
|
|
399
|
+
wait = 200,
|
|
400
|
+
options?: { leading?: boolean;}
|
|
401
|
+
) {
|
|
402
|
+
let last = 0;
|
|
403
|
+
let timeout;
|
|
404
|
+
const leading = options?.leading !== undefined ? options.leading : true;
|
|
405
|
+
|
|
406
|
+
return function (this: any, ...args: any[]) {
|
|
407
|
+
const now = Date.now();
|
|
408
|
+
if (!last && !leading) {
|
|
409
|
+
last = now;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const remaining = wait - (now - last);
|
|
413
|
+
|
|
414
|
+
if (remaining <= 0) {
|
|
415
|
+
if (timeout) {
|
|
416
|
+
clearTimeout(timeout);
|
|
417
|
+
timeout = null;
|
|
418
|
+
}
|
|
419
|
+
last = now;
|
|
420
|
+
func.apply(this, args);
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
}
|
package/assets/video-play.png
DELETED
|
Binary file
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="dialog-video">
|
|
3
|
-
<video
|
|
4
|
-
v-if="isShow"
|
|
5
|
-
id="videoEle"
|
|
6
|
-
class="video-box"
|
|
7
|
-
:src="videoData"
|
|
8
|
-
controls
|
|
9
|
-
autoplay
|
|
10
|
-
/>
|
|
11
|
-
</div>
|
|
12
|
-
</template>
|
|
13
|
-
|
|
14
|
-
<script lang="ts" setup>
|
|
15
|
-
import vue from '../../TencentCloudCustomer/tui-customer-service-plugin-test/adapter-vue';
|
|
16
|
-
import { TUIGlobal } from '@tencentcloud/universal-api';
|
|
17
|
-
import { onLoad, onReady } from '@dcloudio/uni-app';
|
|
18
|
-
const { ref } = vue;
|
|
19
|
-
|
|
20
|
-
const videoData = ref();
|
|
21
|
-
const isShow = ref(false);
|
|
22
|
-
const videoContext = ref();
|
|
23
|
-
onLoad((option: any) => {
|
|
24
|
-
const decodedUrl = decodeURIComponent(option?.videoUrl);
|
|
25
|
-
videoData.value = decodedUrl;
|
|
26
|
-
isShow.value = true;
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
onReady(() => {
|
|
30
|
-
isShow.value = true;
|
|
31
|
-
videoContext.value = TUIGlobal.createVideoContext('videoEle');
|
|
32
|
-
});
|
|
33
|
-
</script>
|
|
34
|
-
<style lang="scss" scoped>
|
|
35
|
-
.dialog-video {
|
|
36
|
-
position: fixed;
|
|
37
|
-
z-index: 999;
|
|
38
|
-
width: 100vw;
|
|
39
|
-
height: 100vh;
|
|
40
|
-
background: rgba(#000, 0.6);
|
|
41
|
-
top: 0;
|
|
42
|
-
left: 0;
|
|
43
|
-
right: 0;
|
|
44
|
-
bottom: 0;
|
|
45
|
-
display: flex;
|
|
46
|
-
justify-content: center;
|
|
47
|
-
align-items: center;
|
|
48
|
-
|
|
49
|
-
.video-box {
|
|
50
|
-
position: absolute;
|
|
51
|
-
width: 100vw;
|
|
52
|
-
height: 100vh;
|
|
53
|
-
top: 0;
|
|
54
|
-
left: 0;
|
|
55
|
-
right: 0;
|
|
56
|
-
bottom: 0;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
</style>
|