@tencentcloud/ai-desk-customer-vue 1.5.4 → 1.5.6
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 +11 -0
- package/components/CustomerServiceChat/index-web.vue +2 -7
- package/components/CustomerServiceChat/message-list/message-elements/message-bubble-web.vue +1 -0
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-branch/index.vue +6 -6
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-mobile.vue +9 -9
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-pc.vue +4 -7
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/index.vue +6 -12
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-rating/message-rating-star.vue +25 -9
- 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-transfer-with-desc.vue +2 -7
- package/interface.ts +2 -2
- package/locales/en/aidesk.ts +3 -0
- package/locales/fil/aidesk.ts +3 -0
- package/locales/id/aidesk.ts +3 -0
- package/locales/ja/aidesk.ts +3 -0
- package/locales/ms/aidesk.ts +3 -0
- package/locales/ru/aidesk.ts +3 -0
- package/locales/th/aidesk.ts +3 -0
- package/locales/vi/aidesk.ts +3 -0
- package/locales/zh_cn/aidesk.ts +3 -0
- package/locales/zh_tw/aidesk.ts +3 -0
- package/package.json +1 -1
- package/server.ts +47 -15
- package/utils/utils.ts +16 -1
package/CHANGELOG.md
CHANGED
|
@@ -256,7 +256,7 @@ const initLanguage = () => {
|
|
|
256
256
|
let navigatorLang = convertLanguageToLowercase(navigator.language);
|
|
257
257
|
language = getValidLanguage(navigatorLang);
|
|
258
258
|
}
|
|
259
|
-
}
|
|
259
|
+
}
|
|
260
260
|
currentLanguage.value = language;
|
|
261
261
|
state.set('currentLanguage', language);
|
|
262
262
|
TUITranslateService.changeLanguage(language);
|
|
@@ -392,13 +392,7 @@ function onCurrentConversationIDUpdate(conversationID: string) {
|
|
|
392
392
|
return;
|
|
393
393
|
}
|
|
394
394
|
|
|
395
|
-
if (currentConversationID.value === conversationID) {
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
395
|
currentConversationID.value = conversationID;
|
|
400
|
-
|
|
401
|
-
// The TUICustomerServicePlugin plugin determines if the current conversation is a customer service conversation, then sets chatType and activates the conversation.
|
|
402
396
|
activeConversation();
|
|
403
397
|
}
|
|
404
398
|
|
|
@@ -451,6 +445,7 @@ function changeLanguage(languageCode: string) {
|
|
|
451
445
|
activeConversation();
|
|
452
446
|
});
|
|
453
447
|
}
|
|
448
|
+
|
|
454
449
|
function activeConversation() {
|
|
455
450
|
TUICore.callService({
|
|
456
451
|
serviceName: TUIConstants.TUICustomerServicePlugin.SERVICE.NAME,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="message-form">
|
|
3
3
|
<BranchPc
|
|
4
|
-
:payload ="
|
|
4
|
+
:payload ="forwardPayload"
|
|
5
5
|
@input-click="handleContentListItemClick"
|
|
6
6
|
/>
|
|
7
7
|
</div>
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import vue from '../../../../../../../adapter-vue';
|
|
12
12
|
import BranchPc from './branch-pc.vue';
|
|
13
13
|
import { customerServicePayloadType } from '../../../../../../../interface';
|
|
14
|
-
const { computed} = vue;
|
|
14
|
+
const { computed } = vue;
|
|
15
15
|
|
|
16
16
|
interface branchItem {
|
|
17
17
|
content: string;
|
|
@@ -35,9 +35,6 @@ export default {
|
|
|
35
35
|
},
|
|
36
36
|
emits: ['sendMessage', 'heightChanged'],
|
|
37
37
|
setup(props: Props, { emit }) {
|
|
38
|
-
const payload = computed<customerServicePayloadType>(() => {
|
|
39
|
-
return props.payload;
|
|
40
|
-
});
|
|
41
38
|
const handleContentListItemClick = (branch: branchItem, cloudCustomData?: string) => {
|
|
42
39
|
emit('sendMessage', { text: branch.content }, cloudCustomData || '');
|
|
43
40
|
};
|
|
@@ -45,8 +42,11 @@ export default {
|
|
|
45
42
|
const handleFormSaveInputSubmit = (text: string) => {
|
|
46
43
|
emit('sendMessage', { text });
|
|
47
44
|
};
|
|
45
|
+
const forwardPayload = computed(() => {
|
|
46
|
+
return props.payload;
|
|
47
|
+
});
|
|
48
48
|
return {
|
|
49
|
-
|
|
49
|
+
forwardPayload,
|
|
50
50
|
handleContentListItemClick,
|
|
51
51
|
handleFormSaveInputSubmit,
|
|
52
52
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="form-mobile-container">
|
|
3
|
-
<div v-if="
|
|
3
|
+
<div v-if="props.payload.nodeStatus !== 2" class="before-form">
|
|
4
4
|
<Icon :src="iconForm" width="60px" height="60px" style="margin:5px 4px"/>
|
|
5
5
|
<div :class="props.payload.nodeStatus === 1 ? 'form-button-disable': 'form-button'" @click="clickShowDialog">
|
|
6
6
|
{{ TUITranslateService.t("AIDesk.立即填写") }}
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
v-for="(item, index) in props.payload.content.inputVariables"
|
|
29
29
|
:key="index"
|
|
30
30
|
>
|
|
31
|
-
<div v-if="
|
|
31
|
+
<div v-if="item.formType == 0 && props.payload.nodeStatus == 0">
|
|
32
32
|
<InputMobile :placeholder="item.placeholder" :variableValue="item.variableValue" :name="item.name" :isRequired="item.isRequired" @input-change="handleInputChange" :validator="item.isRequired == 1 && isValid(item.name)"/>
|
|
33
33
|
</div>
|
|
34
|
-
<div v-else-if="
|
|
34
|
+
<div v-else-if="item.formType == 1 && props.payload.nodeStatus == 0">
|
|
35
35
|
<RadioMobile :chooseItemList="item.chooseItemList" :name="item.name" :isRequired="item.isRequired" @input-change="handleInputChange" :validator="item.isRequired == 1 && isValid(item.name)"/>
|
|
36
36
|
</div>
|
|
37
37
|
<div v-else class="variable-value-container-mobile">
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
</div>
|
|
44
44
|
</div>
|
|
45
45
|
</div>
|
|
46
|
-
<div class="button-container"v-if="
|
|
46
|
+
<div class="button-container" v-if="props.payload.nodeStatus === 0">
|
|
47
47
|
<div class="button" @click="handleSendForm">
|
|
48
48
|
{{ TUITranslateService.t("AIDesk.提交") }}
|
|
49
49
|
</div>
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
</FormPopup>
|
|
53
53
|
</div>
|
|
54
54
|
</div>
|
|
55
|
-
<div v-if="
|
|
55
|
+
<div v-if="props.payload.nodeStatus == 2" class="before-form">
|
|
56
56
|
<div class="icon-container">
|
|
57
57
|
<Icon class="form-icon" :src="iconForm" width="60px" height="60px" style="margin:5px 4px"/>
|
|
58
|
-
<Icon v-if="
|
|
58
|
+
<Icon v-if="props.payload.nodeStatus == 2" class="form-icon-check" width="26px" height="26px" :src="iconFormFilled"/>
|
|
59
59
|
</div>
|
|
60
60
|
<div class="form-button" @click="clickShowDialog">
|
|
61
61
|
{{ TUITranslateService.t("AIDesk.查看内容") }}
|
|
@@ -102,7 +102,6 @@ export default {
|
|
|
102
102
|
const showDialog = ref<boolean>(false);
|
|
103
103
|
const mapValue=ref({});
|
|
104
104
|
const isSubmit = ref<boolean>(false);
|
|
105
|
-
const finishSubmit = ref<boolean>(false);
|
|
106
105
|
const hasNullValue = ref<boolean>(true);
|
|
107
106
|
onMounted(() => {
|
|
108
107
|
let inputVariables = props.payload.content.inputVariables ?? [];
|
|
@@ -163,7 +162,6 @@ export default {
|
|
|
163
162
|
}),
|
|
164
163
|
};
|
|
165
164
|
emit('sendMessage', submitData);
|
|
166
|
-
finishSubmit.value = true;
|
|
167
165
|
isSubmit.value = false;
|
|
168
166
|
};
|
|
169
167
|
const handleInputChange = ({name,value}) => {
|
|
@@ -184,7 +182,6 @@ export default {
|
|
|
184
182
|
clickShowDialog,
|
|
185
183
|
iconClose,
|
|
186
184
|
checkValidator,
|
|
187
|
-
finishSubmit,
|
|
188
185
|
showValue,
|
|
189
186
|
mapValue,
|
|
190
187
|
isSubmit,
|
|
@@ -314,6 +311,7 @@ export default {
|
|
|
314
311
|
display:flex;
|
|
315
312
|
flex-direction: column;
|
|
316
313
|
justify-content: center;
|
|
314
|
+
font-family: PingFangSC-Regular;
|
|
317
315
|
.form-button {
|
|
318
316
|
display:flex;
|
|
319
317
|
justify-content: center;
|
|
@@ -321,6 +319,7 @@ export default {
|
|
|
321
319
|
background-color: #1c66e5;
|
|
322
320
|
color:white;
|
|
323
321
|
border-radius:20px;
|
|
322
|
+
min-width: 100px;
|
|
324
323
|
}
|
|
325
324
|
.form-button-disable {
|
|
326
325
|
background-color: #dbdbdb;
|
|
@@ -329,6 +328,7 @@ export default {
|
|
|
329
328
|
padding: 6px 10px;
|
|
330
329
|
color: white;
|
|
331
330
|
border-radius: 20px;
|
|
331
|
+
min-width: 100px;
|
|
332
332
|
}
|
|
333
333
|
.icon-container {
|
|
334
334
|
position: relative;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<div class="form-title" v-if="checkTip()">
|
|
5
5
|
{{ props.payload.content.tip }}
|
|
6
6
|
</div>
|
|
7
|
-
<div class="form-finish-title-right" v-if="
|
|
7
|
+
<div class="form-finish-title-right" v-if="props.payload.nodeStatus == 2" >
|
|
8
8
|
<Icon :src="iconSucess" style="margin:0px 4px"/>
|
|
9
9
|
<div class="form-finish-title">
|
|
10
10
|
{{ TUITranslateService.t("AIDesk.已提交") }}
|
|
@@ -17,17 +17,17 @@
|
|
|
17
17
|
:key="index"
|
|
18
18
|
>
|
|
19
19
|
<LabelPC :name="item.name" :is-required="item.isRequired" />
|
|
20
|
-
<div v-if="
|
|
20
|
+
<div v-if="item.formType == 0 && props.payload.nodeStatus !== 2">
|
|
21
21
|
<InputPC :placeholder="item.placeholder" :variableValue="item.variableValue" :name="item.name" :isRequired="item.isRequired" @input-change="handleInputChange" :validator="item.isRequired == 1 && isValid(item.name)" :isDisabled="props.payload.nodeStatus === 1"/>
|
|
22
22
|
</div>
|
|
23
|
-
<div v-else-if="
|
|
23
|
+
<div v-else-if="item.formType == 1 && props.payload.nodeStatus !== 2">
|
|
24
24
|
<RadioPC :chooseItemList="item.chooseItemList" :name="item.name" :isRequired="item.isRequired" @input-change="handleInputChange" :validator="item.isRequired == 1 && isValid(item.name)" :isDisabled="props.payload.nodeStatus === 1"/>
|
|
25
25
|
</div>
|
|
26
26
|
<div v-else class="variable-value-container">
|
|
27
27
|
{{ item.variableValue == '' || item.variableValue == null ? mapValue[item.name] : item.variableValue}}
|
|
28
28
|
</div>
|
|
29
29
|
</div>
|
|
30
|
-
<div class="button-container"v-if="
|
|
30
|
+
<div class="button-container" v-if="props.payload.nodeStatus !== 2">
|
|
31
31
|
<div :class="props.payload.nodeStatus === 1 ? 'button-disable' : 'button'" @click="handleSendForm">
|
|
32
32
|
{{ TUITranslateService.t("AIDesk.提交") }}
|
|
33
33
|
</div>
|
|
@@ -66,7 +66,6 @@ export default {
|
|
|
66
66
|
setup(props: Props, { emit }) {
|
|
67
67
|
const mapValue=ref({});
|
|
68
68
|
const isSubmit = ref<boolean>(false);
|
|
69
|
-
const finishSubmit = ref<boolean>(false);
|
|
70
69
|
const hasNullValue = ref<boolean>(true);
|
|
71
70
|
onMounted(()=>{
|
|
72
71
|
let inputVariables = props.payload.content.inputVariables ?? [];
|
|
@@ -118,7 +117,6 @@ export default {
|
|
|
118
117
|
}),
|
|
119
118
|
};
|
|
120
119
|
emit('sendMessage', submitData);
|
|
121
|
-
finishSubmit.value = true;
|
|
122
120
|
isSubmit.value = false;
|
|
123
121
|
};
|
|
124
122
|
|
|
@@ -141,7 +139,6 @@ export default {
|
|
|
141
139
|
handleInputChange,
|
|
142
140
|
iconSucess,
|
|
143
141
|
checkValidator,
|
|
144
|
-
finishSubmit,
|
|
145
142
|
showValue,
|
|
146
143
|
mapValue,
|
|
147
144
|
isSubmit,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div v-if="isPC" class="message-input">
|
|
3
|
-
<FormPC :payload="
|
|
3
|
+
<FormPC :payload="forwardPayload" @sendMessage="handleSendForm" />
|
|
4
4
|
</div>
|
|
5
5
|
<div v-else>
|
|
6
|
-
<FormMobile :payload="
|
|
6
|
+
<FormMobile :payload="forwardPayload" @sendMessage="handleSendForm" @showFormPopup="handleShowFormPopup"/>
|
|
7
7
|
</div>
|
|
8
8
|
</template>
|
|
9
9
|
|
|
@@ -15,11 +15,6 @@ import { customerServicePayloadType } from '../../../../../../../interface';
|
|
|
15
15
|
import { isPC } from '../../../../../../../utils/env';
|
|
16
16
|
const { computed } = vue;
|
|
17
17
|
|
|
18
|
-
interface branchItem {
|
|
19
|
-
content: string;
|
|
20
|
-
desc: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
18
|
interface Props {
|
|
24
19
|
payload: customerServicePayloadType;
|
|
25
20
|
}
|
|
@@ -37,18 +32,17 @@ export default {
|
|
|
37
32
|
},
|
|
38
33
|
emits: ['sendMessage','showFormPopup'],
|
|
39
34
|
setup(props: Props, { emit }) {
|
|
40
|
-
const payloads = computed<customerServicePayloadType>(() => {
|
|
41
|
-
return props.payload;
|
|
42
|
-
});
|
|
43
35
|
const handleSendForm = (data: any) => {
|
|
44
36
|
emit('sendMessage', data);
|
|
45
37
|
};
|
|
46
38
|
const handleShowFormPopup = (data: boolean) => {
|
|
47
39
|
emit('showFormPopup', data);
|
|
48
40
|
}
|
|
49
|
-
|
|
41
|
+
const forwardPayload = computed(() => {
|
|
42
|
+
return props.payload;
|
|
43
|
+
});
|
|
50
44
|
return {
|
|
51
|
-
|
|
45
|
+
forwardPayload,
|
|
52
46
|
handleSendForm,
|
|
53
47
|
isPC,
|
|
54
48
|
handleShowFormPopup
|
|
@@ -30,15 +30,21 @@
|
|
|
30
30
|
</div>
|
|
31
31
|
</div>
|
|
32
32
|
</div>
|
|
33
|
-
<div
|
|
34
|
-
{
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
?
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
<div>
|
|
34
|
+
<div :style="{ marginTop: 10 + 'px', marginBottom: 10 + 'px', wordBreak: 'normal' }">
|
|
35
|
+
{{
|
|
36
|
+
hoverValue === -1
|
|
37
|
+
? value === -1
|
|
38
|
+
? TUITranslateService.t("AIDesk.如果满意请给好评哦~")
|
|
39
|
+
: desc[value]
|
|
40
|
+
: desc[hoverValue]
|
|
41
|
+
}}
|
|
42
|
+
</div>
|
|
43
|
+
<div class="hidden-desc">
|
|
44
|
+
{{ TUITranslateService.t("AIDesk.如果满意请给好评哦~") }}
|
|
45
|
+
</div>
|
|
41
46
|
</div>
|
|
47
|
+
|
|
42
48
|
<button
|
|
43
49
|
class="submit-button"
|
|
44
50
|
:disabled="hasReply || hasExpire"
|
|
@@ -201,11 +207,11 @@ export default {
|
|
|
201
207
|
}
|
|
202
208
|
|
|
203
209
|
.message-rating-star {
|
|
210
|
+
font-family: PingFangSC-Regular;
|
|
204
211
|
text-align: center;
|
|
205
212
|
display: flex;
|
|
206
213
|
flex-flow: column wrap;
|
|
207
214
|
justify-content: center;
|
|
208
|
-
|
|
209
215
|
align-items: center;
|
|
210
216
|
}
|
|
211
217
|
|
|
@@ -228,4 +234,14 @@ export default {
|
|
|
228
234
|
width: 62%;
|
|
229
235
|
}
|
|
230
236
|
|
|
237
|
+
.hidden-desc {
|
|
238
|
+
width: 100%;
|
|
239
|
+
overflow-wrap: break-word;
|
|
240
|
+
word-break: normal;
|
|
241
|
+
visibility: hidden;
|
|
242
|
+
padding: 0;
|
|
243
|
+
margin: 0;
|
|
244
|
+
height: 0;
|
|
245
|
+
}
|
|
246
|
+
|
|
231
247
|
</style>
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="['text', isPC && 'text-select']">
|
|
3
|
-
{{
|
|
3
|
+
{{ description }}
|
|
4
4
|
</div>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script lang="ts">
|
|
8
|
-
import vue from '../../../../../../adapter-vue';
|
|
9
8
|
import { customerServicePayloadType } from '../../../../../../interface';
|
|
10
9
|
import { isPC } from '../../../../../../utils/env';
|
|
11
|
-
const { computed } = vue;
|
|
12
10
|
|
|
13
11
|
interface Props {
|
|
14
12
|
payload: customerServicePayloadType;
|
|
@@ -22,11 +20,8 @@ export default {
|
|
|
22
20
|
},
|
|
23
21
|
},
|
|
24
22
|
setup(props: Props) {
|
|
25
|
-
const payload = computed<customerServicePayloadType>(() => {
|
|
26
|
-
return props.payload;
|
|
27
|
-
});
|
|
28
23
|
return {
|
|
29
|
-
props,
|
|
24
|
+
description: props.payload.description,
|
|
30
25
|
isPC,
|
|
31
26
|
};
|
|
32
27
|
},
|
package/interface.ts
CHANGED
|
@@ -16,7 +16,7 @@ export interface customerServicePayloadType {
|
|
|
16
16
|
nodeID?: string;
|
|
17
17
|
env?: string;
|
|
18
18
|
}
|
|
19
|
-
description?: string
|
|
19
|
+
description?: string;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
interface IMenuItem {
|
|
@@ -235,7 +235,7 @@ export interface ITransferToTaskFlowModel {
|
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
export interface ITransferToHumanModel {
|
|
238
|
-
groupID?:
|
|
238
|
+
groupID?: number;
|
|
239
239
|
specificMemberList?: Array<string>;
|
|
240
240
|
description?: string;
|
|
241
241
|
}
|
package/locales/en/aidesk.ts
CHANGED
|
@@ -30,5 +30,8 @@ const AIDesk = {
|
|
|
30
30
|
"file 大小超过 100MB,无法发送":"Unable to send the file as it exceeds 100 MB",
|
|
31
31
|
"image 大小超过 20MB,无法发送":"Unable to send the image as it exceeds 20 MB",
|
|
32
32
|
"video 大小超过 100MB,无法发送":"Unable to send the video as it exceeds 100 MB",
|
|
33
|
+
"userID 只能包含可打印 ASCII 字符": "The userID can only contain printable ASCII characters",
|
|
34
|
+
"userID 不能包含'administrator'": "The userID cannot contain the string 'administrator'",
|
|
35
|
+
"userID 长度不能超过45字节": "The length of the userID cannot exceed 45 bytes",
|
|
33
36
|
}
|
|
34
37
|
export default AIDesk;
|
package/locales/fil/aidesk.ts
CHANGED
|
@@ -30,5 +30,8 @@ const AIDesk = {
|
|
|
30
30
|
"file 大小超过 100MB,无法发送":"Lampas sa 100MB ang file, hindi maipadala",
|
|
31
31
|
"image 大小超过 20MB,无法发送":"Hindi maipadala ang larawan dahil lampas ito sa 20 MB",
|
|
32
32
|
"video 大小超过 100MB,无法发送":"Hindi maipadala ang video dahil lampas ito sa 100 MB",
|
|
33
|
+
"userID 只能包含可打印 ASCII 字符": "Ang UserID ay dapat naglalaman lamang ng printable ASCII characters",
|
|
34
|
+
"userID 不能包含'administrator'": "Ang UserID ay hindi dapat maglaman ng 'administrator'",
|
|
35
|
+
"userID 长度不能超过45字节": "Ang haba ng UserID ay hindi dapat lumampas sa 45 bytes",
|
|
33
36
|
}
|
|
34
37
|
export default AIDesk;
|
package/locales/id/aidesk.ts
CHANGED
|
@@ -30,5 +30,8 @@ const AIDesk = {
|
|
|
30
30
|
"file 大小超过 100MB,无法发送":"Ukuran file melebihi 100MB, tidak dapat dikirim",
|
|
31
31
|
"image 大小超过 20MB,无法发送":"Tidak dapat mengirim gambar karena melebihi 20 MB",
|
|
32
32
|
"video 大小超过 100MB,无法发送":"Tidak dapat mengirim video karena melebihi 100 MB",
|
|
33
|
+
"userID 只能包含可打印 ASCII 字符": "UserID hanya boleh berisi karakter ASCII yang dapat dicetak",
|
|
34
|
+
"userID 不能包含'administrator'": "UserID tidak boleh mengandung 'administrator'",
|
|
35
|
+
"userID 长度不能超过45字节": "Panjang UserID tidak boleh melebihi 45 byte",
|
|
33
36
|
}
|
|
34
37
|
export default AIDesk;
|
package/locales/ja/aidesk.ts
CHANGED
|
@@ -30,5 +30,8 @@ const AIDesk = {
|
|
|
30
30
|
"file 大小超过 100MB,无法发送":"ファイルサイズが100MBを超えているため送信できません",
|
|
31
31
|
"image 大小超过 20MB,无法发送":"画像のサイズが20MBを超えているため送信できません",
|
|
32
32
|
"video 大小超过 100MB,无法发送":"動画のサイズが100MBを超えているため送信できません",
|
|
33
|
+
"userID 只能包含可打印 ASCII 字符": "UserIDは印字可能なASCII文字のみを含める必要があります",
|
|
34
|
+
"userID 不能包含'administrator'": "UserIDに'administrator'を含めることはできません",
|
|
35
|
+
"userID 长度不能超过45字节": "UserIDの長さは45バイトを超えてはいけません",
|
|
33
36
|
}
|
|
34
37
|
export default AIDesk;
|
package/locales/ms/aidesk.ts
CHANGED
|
@@ -30,5 +30,8 @@ const AIDesk = {
|
|
|
30
30
|
"file 大小超过 100MB,无法发送":"Saiz fail melebihi 100MB, tidak boleh dihantar",
|
|
31
31
|
"image 大小超过 20MB,无法发送":"Tidak dapat menghantar gambar kerana melebihi 20 MB",
|
|
32
32
|
"video 大小超过 100MB,无法发送":"Tidak dapat menghantar video kerana melebihi 100 MB",
|
|
33
|
+
"userID 只能包含可打印 ASCII 字符": "UserID hanya boleh mengandung aksara ASCII yang boleh dicetak",
|
|
34
|
+
"userID 不能包含'administrator'": "UserID tidak boleh mengandung 'administrator'",
|
|
35
|
+
"userID 长度不能超过45字节": "Panjang UserID tidak boleh melebihi 45 bait",
|
|
33
36
|
}
|
|
34
37
|
export default AIDesk;
|
package/locales/ru/aidesk.ts
CHANGED
|
@@ -30,5 +30,8 @@ const AIDesk = {
|
|
|
30
30
|
"file 大小超过 100MB,无法发送":"Размер файла превышает 100MB, отправка невозможна",
|
|
31
31
|
"image 大小超过 20MB,无法发送":"Невозможно отправить изображение, так как оно превышает 20 MB",
|
|
32
32
|
"video 大小超过 100MB,无法发送":"Невозможно отправить видео, так как оно превышает 100 MB",
|
|
33
|
+
"userID 只能包含可打印 ASCII 字符": "UserID должен содержать только печатные символы ASCII",
|
|
34
|
+
"userID 不能包含'administrator'": "UserID не должен содержать 'administrator'",
|
|
35
|
+
"userID 长度不能超过45字节": "Длина UserID не должна превышать 45 байт",
|
|
33
36
|
}
|
|
34
37
|
export default AIDesk;
|
package/locales/th/aidesk.ts
CHANGED
|
@@ -30,5 +30,8 @@ const AIDesk = {
|
|
|
30
30
|
"file 大小超过 100MB,无法发送":"ขนาดไฟล์เกิน 100MB ไม่สามารถส่งได้",
|
|
31
31
|
"image 大小超过 20MB,无法发送":"ไม่สามารถส่งรูปภาพได้เนื่องจากขนาดเกิน 20 MB",
|
|
32
32
|
"video 大小超过 100MB,无法发送":"ไม่สามารถส่งวิดีโอได้เนื่องจากขนาดเกิน 100 MB",
|
|
33
|
+
"userID 只能包含可打印 ASCII 字符": "UserID ต้องมีเฉพาะตัวอักษร ASCII ที่พิมพ์ได้เท่านั้น",
|
|
34
|
+
"userID 不能包含'administrator'": "UserID ห้ามมี 'administrator'",
|
|
35
|
+
"userID 长度不能超过45字节": "ความยาว UserID ต้องไม่เกิน 45 ไบต์",
|
|
33
36
|
}
|
|
34
37
|
export default AIDesk;
|
package/locales/vi/aidesk.ts
CHANGED
|
@@ -30,5 +30,8 @@ const AIDesk = {
|
|
|
30
30
|
"file 大小超过 100MB,无法发送":"Kích thước tệp vượt quá 100MB, không thể gửi",
|
|
31
31
|
"image 大小超过 20MB,无法发送":"Không thể gửi hình ảnh do vượt quá 20 MB",
|
|
32
32
|
"video 大小超过 100MB,无法发送":"Không thể gửi video do vượt quá 100 MB",
|
|
33
|
+
"userID 只能包含可打印 ASCII 字符": "UserID chỉ được chứa ký tự ASCII có thể in được",
|
|
34
|
+
"userID 不能包含'administrator'": "UserID không được chứa 'administrator'",
|
|
35
|
+
"userID 长度不能超过45字节": "Độ dài UserID không được vượt quá 45 byte",
|
|
33
36
|
}
|
|
34
37
|
export default AIDesk;
|
package/locales/zh_cn/aidesk.ts
CHANGED
|
@@ -30,5 +30,8 @@ const AIDesk = {
|
|
|
30
30
|
"file 大小超过 100MB,无法发送": "file 大小超过 100MB,无法发送",
|
|
31
31
|
"image 大小超过 20MB,无法发送":"image 大小超过 20MB,无法发送",
|
|
32
32
|
"video 大小超过 100MB,无法发送":"video 大小超过 100MB,无法发送",
|
|
33
|
+
"userID 只能包含可打印 ASCII 字符": "userID 只能包含可打印 ASCII 字符",
|
|
34
|
+
"userID 不能包含'administrator'": "userID 不能包含'administrator'",
|
|
35
|
+
"userID 长度不能超过45字节": "userID 长度不能超过45字节",
|
|
33
36
|
}
|
|
34
37
|
export default AIDesk;
|
package/locales/zh_tw/aidesk.ts
CHANGED
|
@@ -30,5 +30,8 @@ const AIDesk = {
|
|
|
30
30
|
"file 大小超过 100MB,无法发送":"檔案大小超過100MB,無法傳送",
|
|
31
31
|
"image 大小超过 20MB,无法发送":"圖片大小超過20MB,無法傳送",
|
|
32
32
|
"video 大小超过 100MB,无法发送":"影片大小超過100MB,無法傳送",
|
|
33
|
+
"userID 只能包含可打印 ASCII 字符": "userID 只能包含可打印 ASCII 字元",
|
|
34
|
+
"userID 不能包含'administrator'": "userID 不能包含'administrator'",
|
|
35
|
+
"userID 长度不能超过45字节": "userID 長度不能超過45位元組",
|
|
33
36
|
}
|
|
34
37
|
export default AIDesk;
|
package/package.json
CHANGED
package/server.ts
CHANGED
|
@@ -19,9 +19,9 @@ import TUIChatEngine, {
|
|
|
19
19
|
import Log from './utils/logger';
|
|
20
20
|
import { version } from './package.json'
|
|
21
21
|
import { Toast, TOAST_TYPE } from "./components/common/Toast/index-web";
|
|
22
|
-
import { switchReadStatus, transferToHuman, transferToTaskFlow } from "./utils/utils";
|
|
22
|
+
import { switchReadStatus, transferToHuman, transferToTaskFlow, validateUserID } from "./utils/utils";
|
|
23
23
|
import state from "./utils/state";
|
|
24
|
-
import {
|
|
24
|
+
import { USER_DEFAULT_AVATAR } from "./constant";
|
|
25
25
|
import { vueVersion } from "./adapter-vue-web";
|
|
26
26
|
import { ITransferToHumanModel, ITransferToTaskFlowModel } from './interface';
|
|
27
27
|
|
|
@@ -46,6 +46,7 @@ export default class TUICustomerServer {
|
|
|
46
46
|
private currentCustomerServiceID: string;
|
|
47
47
|
private loggedInUserID: string;
|
|
48
48
|
private myProfile: IProfile;
|
|
49
|
+
private paramsForActiveAgain: any;
|
|
49
50
|
constructor() {
|
|
50
51
|
TUICore.registerService(TUIConstants.TUICustomerServicePlugin.SERVICE.NAME, this);
|
|
51
52
|
TUICore.registerExtension(TUIConstants.TUIContact.EXTENSION.CONTACT_LIST.EXT_ID, this);
|
|
@@ -63,9 +64,9 @@ export default class TUICustomerServer {
|
|
|
63
64
|
return TUICustomerServer.instance;
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
private loginCustomerUIKit(SDKAppID:number, userID:string, userSig:string) {
|
|
67
|
+
private async loginCustomerUIKit(SDKAppID:number, userID:string, userSig:string) {
|
|
67
68
|
clearChatStorage(SDKAppID, userID);
|
|
68
|
-
TUIChatEngine.login({
|
|
69
|
+
return TUIChatEngine.login({
|
|
69
70
|
SDKAppID,
|
|
70
71
|
userID,
|
|
71
72
|
userSig,
|
|
@@ -74,7 +75,7 @@ export default class TUICustomerServer {
|
|
|
74
75
|
Log.i(`login success. userID:${userID}`);
|
|
75
76
|
this.isLoggedIn = true;
|
|
76
77
|
this.loggedInUserID = userID;
|
|
77
|
-
|
|
78
|
+
this.switchConversation(`C2C${this.currentCustomerServiceID}`);
|
|
78
79
|
switchReadStatus(state.get('showReadStatus'));
|
|
79
80
|
TUIChatEngine.chat.callExperimentalAPI('isFeatureEnabledForStat', Math.pow(2, 42));
|
|
80
81
|
})
|
|
@@ -88,24 +89,45 @@ export default class TUICustomerServer {
|
|
|
88
89
|
})
|
|
89
90
|
}
|
|
90
91
|
|
|
91
|
-
public init(SDKAppID:number, userID:string, userSig:string) {
|
|
92
|
+
public async init(SDKAppID:number, userID:string, userSig:string) {
|
|
92
93
|
Log.l(`TUICustomerServer.init vueVersion:${vueVersion} version:${version} SDKAppID:${SDKAppID} userID:${userID}` +
|
|
93
94
|
` isLoggedIn:${this.isLoggedIn} loggedInUserID:${this.loggedInUserID} currentCustomerServiceID:${this.currentCustomerServiceID}`);
|
|
95
|
+
if (userID) {
|
|
96
|
+
let ret = validateUserID(userID);
|
|
97
|
+
if (ret > 0) {
|
|
98
|
+
setTimeout(() => {
|
|
99
|
+
let reason = '';
|
|
100
|
+
if (ret === 1) {
|
|
101
|
+
reason = TUITranslateService.t("AIDesk.userID 只能包含可打印 ASCII 字符");
|
|
102
|
+
} else if (ret === 2) {
|
|
103
|
+
reason = TUITranslateService.t("AIDesk.userID 不能包含'administrator'");
|
|
104
|
+
} else if (ret === 3) {
|
|
105
|
+
reason = TUITranslateService.t("AIDesk.userID 长度不能超过45字节");
|
|
106
|
+
}
|
|
107
|
+
Toast({
|
|
108
|
+
message: reason,
|
|
109
|
+
type: TOAST_TYPE.ERROR,
|
|
110
|
+
duration: 30000,
|
|
111
|
+
});
|
|
112
|
+
}, 500);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
94
116
|
if (this.isLoggedIn) {
|
|
95
117
|
if (this.loggedInUserID === userID) {
|
|
96
|
-
|
|
118
|
+
await this.switchConversation(`C2C${this.currentCustomerServiceID}`);
|
|
97
119
|
return;
|
|
98
120
|
}
|
|
99
|
-
this.unInit().finally(() => {
|
|
121
|
+
return this.unInit().finally(() => {
|
|
100
122
|
this.isLoggedIn = false;
|
|
101
123
|
this.loginCustomerUIKit(SDKAppID, userID, userSig);
|
|
102
124
|
});
|
|
103
125
|
} else {
|
|
104
|
-
this.loginCustomerUIKit(SDKAppID, userID, userSig);
|
|
126
|
+
return this.loginCustomerUIKit(SDKAppID, userID, userSig);
|
|
105
127
|
}
|
|
106
128
|
}
|
|
107
129
|
|
|
108
|
-
public initWithProfile(options: IInitWithProfile) {
|
|
130
|
+
public async initWithProfile(options: IInitWithProfile) {
|
|
109
131
|
const { SDKAppID, userID, userSig, nickName, avatar, customerServiceID } = options;
|
|
110
132
|
Log.l(`TUICustomerServer.initWithProfile version:${version}`);
|
|
111
133
|
if (nickName) {
|
|
@@ -118,10 +140,10 @@ export default class TUICustomerServer {
|
|
|
118
140
|
if (customerServiceID) {
|
|
119
141
|
this.currentCustomerServiceID = customerServiceID;
|
|
120
142
|
}
|
|
121
|
-
this.init(SDKAppID, userID, userSig);
|
|
143
|
+
return this.init(SDKAppID, userID, userSig);
|
|
122
144
|
}
|
|
123
145
|
|
|
124
|
-
public unInit() {
|
|
146
|
+
public async unInit() {
|
|
125
147
|
this.isLoggedIn = false;
|
|
126
148
|
return TUIChatEngine.logout();
|
|
127
149
|
}
|
|
@@ -228,9 +250,18 @@ export default class TUICustomerServer {
|
|
|
228
250
|
}
|
|
229
251
|
}
|
|
230
252
|
|
|
253
|
+
private async switchConversation(conversationID: string) {
|
|
254
|
+
const ret = await TUIConversationService.switchConversation(conversationID);
|
|
255
|
+
// -100002 即要切换的会话 ID 跟当前已打开的会话 ID 相同,这个时候我们重发 src 7,确保服务流状态正确
|
|
256
|
+
if (ret.code === -100002) {
|
|
257
|
+
this.activeServiceFlow(this.paramsForActiveAgain);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
231
261
|
// 激活会话服务流
|
|
232
262
|
private activeServiceFlow(params: any) {
|
|
233
|
-
Log.i(`activeServiceFlow params: language:${params.robotLang} country:${params.country} timezone:${params.timezone}`)
|
|
263
|
+
Log.i(`TUICustomerServer.activeServiceFlow params: language:${params.robotLang} country:${params.country} timezone:${params.timezone}`);
|
|
264
|
+
this.paramsForActiveAgain = { ...params };
|
|
234
265
|
TUIChatService.sendCustomMessage({
|
|
235
266
|
to: params.conversationID.slice(3),
|
|
236
267
|
conversationType: TUIChatEngine.TYPES.CONV_C2C,
|
|
@@ -238,8 +269,8 @@ export default class TUICustomerServer {
|
|
|
238
269
|
data: JSON.stringify({
|
|
239
270
|
src: '7',
|
|
240
271
|
customerServicePlugin: 0,
|
|
241
|
-
triggeredContent: {
|
|
242
|
-
language: params.robotLang,
|
|
272
|
+
triggeredContent: {
|
|
273
|
+
language: params.robotLang,
|
|
243
274
|
country: params.country,
|
|
244
275
|
timezone: params.timezone,
|
|
245
276
|
}
|
|
@@ -247,5 +278,6 @@ export default class TUICustomerServer {
|
|
|
247
278
|
},
|
|
248
279
|
}, { onlineUserOnly: true });
|
|
249
280
|
TUIStore.update(StoreName.CUSTOM, "isInSession", true);
|
|
281
|
+
Log.w(`TUICustomerServer.activeServiceFlow src 7 sent`);
|
|
250
282
|
}
|
|
251
283
|
}
|
package/utils/utils.ts
CHANGED
|
@@ -288,7 +288,7 @@ export function transferToTaskFlow(conversationID: string, taskFlowID: number, d
|
|
|
288
288
|
},{ onlineUserOnly: description ? false : true });
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
export function transferToHuman(conversationID: string, groupID?:
|
|
291
|
+
export function transferToHuman(conversationID: string, groupID?: number, specificMemberList?: Array<string>, description?: string) {
|
|
292
292
|
if (!groupID && (!specificMemberList || specificMemberList.length === 0)) {
|
|
293
293
|
Log.w(`groupID or specificMemberList is required`);
|
|
294
294
|
return;
|
|
@@ -306,4 +306,19 @@ export function transferToHuman(conversationID: string, groupID?: string, specif
|
|
|
306
306
|
})
|
|
307
307
|
}
|
|
308
308
|
},{ onlineUserOnly: description ? false : true });
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export function validateUserID(userID: string) {
|
|
312
|
+
let ret = 0;
|
|
313
|
+
if (!/^[\x20-\x7E]+$/.test(userID)) {
|
|
314
|
+
ret = 1;
|
|
315
|
+
}
|
|
316
|
+
if (userID.toLowerCase().includes('administrator')) {
|
|
317
|
+
ret = 2;
|
|
318
|
+
}
|
|
319
|
+
const byteSize = new TextEncoder().encode(userID).length;
|
|
320
|
+
if (byteSize > 45) {
|
|
321
|
+
ret = 3;
|
|
322
|
+
}
|
|
323
|
+
return ret;
|
|
309
324
|
}
|