@tencentcloud/ai-desk-customer-vue 1.1.0 → 1.4.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +16 -3
  2. package/assets/customer_avatar.png +0 -0
  3. package/assets/face.svg +10 -0
  4. package/assets/files.svg +5 -0
  5. package/assets/image.svg +8 -0
  6. package/assets/rating_tool_icon.svg +5 -0
  7. package/assets/rating_tool_icon_h5.svg +1 -0
  8. package/assets/video.svg +8 -0
  9. package/assets/video_h5.svg +1 -0
  10. package/components/CustomerServiceChat/chat-header/index-web.vue +16 -14
  11. package/components/CustomerServiceChat/index-web.vue +72 -16
  12. package/components/CustomerServiceChat/message-input/index-web.vue +31 -5
  13. package/components/CustomerServiceChat/message-input/message-input-editor-web.vue +24 -0
  14. package/components/CustomerServiceChat/message-input-toolbar/emoji-picker/emoji-picker-dialog.vue +1 -1
  15. package/components/CustomerServiceChat/message-input-toolbar/emoji-picker/index.vue +1 -1
  16. package/components/CustomerServiceChat/message-input-toolbar/file-upload/index.vue +6 -8
  17. package/components/CustomerServiceChat/message-input-toolbar/image-upload/index.vue +11 -16
  18. package/components/CustomerServiceChat/message-input-toolbar/index-web.vue +61 -18
  19. package/components/CustomerServiceChat/message-input-toolbar/rating-tool/index.vue +72 -0
  20. package/components/CustomerServiceChat/message-input-toolbar/toolbar-item-container/style/h5.scss +10 -1
  21. package/components/CustomerServiceChat/message-input-toolbar/user-define-input-tool.vue +80 -0
  22. package/components/CustomerServiceChat/message-input-toolbar/video-upload/index.vue +9 -14
  23. package/components/CustomerServiceChat/message-list/index-web.vue +34 -6
  24. package/components/CustomerServiceChat/message-list/message-elements/message-bubble-web.vue +65 -19
  25. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/marked.ts +1 -1
  26. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-branch.vue +30 -11
  27. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-concurrency-limit.vue +40 -0
  28. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-desk.vue +29 -7
  29. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-branch/branch-pc.vue +107 -73
  30. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-branch/index.vue +53 -52
  31. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/component-mobile/input-mobile.vue +73 -80
  32. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/component-mobile/label-mobile.vue +21 -24
  33. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/component-mobile/radios-mobile.vue +115 -116
  34. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/component-pc/input-pc.vue +69 -73
  35. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/component-pc/label-pc.vue +21 -25
  36. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/component-pc/radio-pc.vue +87 -77
  37. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-mobile.vue +213 -200
  38. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-pc.vue +122 -113
  39. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/index.vue +7 -7
  40. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-order.vue +141 -0
  41. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-rich-text.vue +5 -1
  42. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-stream.vue +25 -1
  43. package/components/CustomerServiceChat/message-list/message-elements/message-file.vue +1 -1
  44. package/components/CustomerServiceChat/message-list/scroll-button/index.vue +18 -6
  45. package/components/CustomerServiceChat/message-list/style/web.scss +2 -1
  46. package/components/CustomerServiceChat/message-toolbar-button/index.vue +111 -42
  47. package/components/CustomerServiceChat/message-toolbar-button/toolbar-button-end-human-service.vue +59 -0
  48. package/components/CustomerServiceChat/message-toolbar-button/toolbar-button-human-service.vue +55 -0
  49. package/components/CustomerServiceChat/message-toolbar-button/toolbar-button-service-rating.vue +59 -0
  50. package/components/common/BottomPopup/index.vue +1 -1
  51. package/constant.ts +25 -4
  52. package/interface.ts +35 -5
  53. package/locales/en/aidesk.ts +6 -3
  54. package/locales/fil/aidesk.ts +4 -1
  55. package/locales/id/aidesk.ts +7 -4
  56. package/locales/ja/aidesk.ts +5 -2
  57. package/locales/ms/aidesk.ts +5 -2
  58. package/locales/ru/aidesk.ts +6 -3
  59. package/locales/th/aidesk.ts +4 -1
  60. package/locales/vi/aidesk.ts +5 -2
  61. package/locales/zh_cn/aidesk.ts +5 -3
  62. package/locales/zh_tw/aidesk.ts +4 -1
  63. package/package.json +1 -1
  64. package/server.ts +11 -2
  65. package/utils/state.js +30 -0
  66. package/utils/utils.ts +48 -1
  67. package/assets/face.png +0 -0
  68. package/assets/files.png +0 -0
  69. package/assets/image.png +0 -0
  70. package/assets/video.png +0 -0
@@ -1,72 +1,67 @@
1
1
  <template>
2
- <div>
3
- <div v-if="!finishSubmit && props.payload.nodeStatus == 0" class="before-form">
4
- <Icon :src="iconForm" width="60px" height="60px" style="margin:5px 4px"/>
5
- <div class="form-button" @click="clickShowDialog">
6
- {{TUITranslateService.t("AIDesk.立即填写")}}
7
- </div>
2
+ <div class="form-mobile-container">
3
+ <div v-if="!finishSubmit && props.payload.nodeStatus !== 2" class="before-form">
4
+ <Icon :src="iconForm" width="60px" height="60px" style="margin:5px 4px"/>
5
+ <div :class="props.payload.nodeStatus === 1 ? 'form-button-disable': 'form-button'" @click="clickShowDialog">
6
+ {{ TUITranslateService.t("AIDesk.立即填写") }}
7
+ </div>
8
8
  </div>
9
9
  <div class="edit-form">
10
- <div class="edit-form-item">
11
- <FormPopup
12
- class="form-item"
13
- :show="showDialog"
14
- :showHeaderCloseButton="false"
15
- @onClose="closeDialog"
16
- title=""
17
- >
18
- <div style="height:100%;overflow-y: auto;">
19
- <div class="dialog-title">
20
- <div>
21
- {{ props.payload.content.tip }}
22
- </div>
23
- <div @click="closeDialog">
24
- <Icon :src="iconClose" width="16px" height="16px"/>
25
- </div>
26
- </div>
27
- <div
28
- v-for="(item, index) in props.payload.content.inputVariables"
29
- :key="index"
30
- >
31
- <div v-if="!finishSubmit && item.formType == 0 && props.payload.nodeStatus == 0">
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
- </div>
34
- <div v-else-if="!finishSubmit && item.formType == 1 && props.payload.nodeStatus == 0">
35
- <RadioMobile :chooseItemList="item.chooseItemList" :name="item.name" :isRequired="item.isRequired" @input-change="handleInputChange" :validator="item.isRequired == 1 && isValid(item.name)"/>
36
- </div>
37
- <div v-else class="variable-value-container-mobile">
38
- <div style="width:70px">
39
- {{ item.name }}
40
- </div>
41
- <div>
42
- {{ item.variableValue == '' || item.variableValue == null ? mapValue[item.name] : item.variableValue}}
43
- </div>
44
-
45
- </div>
46
- </div>
47
- <div class="button-container"v-if="!finishSubmit && props.payload.nodeStatus == 0">
48
- <div class="button" @click="handleSendForm">
49
- {{TUITranslateService.t("AIDesk.提交")}}
50
- </div>
51
-
52
- </div>
53
- </div>
54
-
55
- </FormPopup>
56
- </div>
10
+ <div class="edit-form-item">
11
+ <FormPopup
12
+ class="form-item"
13
+ :show="showDialog"
14
+ :showHeaderCloseButton="false"
15
+ @onClose="closeDialog"
16
+ title=""
17
+ >
18
+ <div style="height:100%;overflow-y: auto;">
19
+ <div class="dialog-title">
20
+ <div>
21
+ {{ props.payload.content.tip }}
22
+ </div>
23
+ <div @click="closeDialog">
24
+ <Icon :src="iconClose" width="16px" height="16px"/>
25
+ </div>
26
+ </div>
27
+ <div
28
+ v-for="(item, index) in props.payload.content.inputVariables"
29
+ :key="index"
30
+ >
31
+ <div v-if="!finishSubmit && item.formType == 0 && props.payload.nodeStatus == 0">
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
+ </div>
34
+ <div v-else-if="!finishSubmit && item.formType == 1 && props.payload.nodeStatus == 0">
35
+ <RadioMobile :chooseItemList="item.chooseItemList" :name="item.name" :isRequired="item.isRequired" @input-change="handleInputChange" :validator="item.isRequired == 1 && isValid(item.name)"/>
36
+ </div>
37
+ <div v-else class="variable-value-container-mobile">
38
+ <div class="variable-value-label">
39
+ {{ item.name }}
40
+ </div>
41
+ <div class="variable-value">
42
+ {{ item.variableValue == '' || item.variableValue == null ? mapValue[item.name] : item.variableValue}}
43
+ </div>
44
+ </div>
45
+ </div>
46
+ <div class="button-container"v-if="!finishSubmit && props.payload.nodeStatus === 0">
47
+ <div class="button" @click="handleSendForm">
48
+ {{ TUITranslateService.t("AIDesk.提交") }}
49
+ </div>
50
+ </div>
51
+ </div>
52
+ </FormPopup>
53
+ </div>
57
54
  </div>
58
- <div v-if="finishSubmit || props.payload.nodeStatus != 0" class="before-form">
59
- <div class="icon-container">
60
- <Icon class="form-icon" :src="iconForm" width="60px" height="60px" style="margin:5px 4px"/>
61
- <Icon v-if="finishSubmit || props.payload.nodeStatus == 2" class="form-icon-check" width="26px" height="26px" :src="iconFormFilled"/>
62
- </div>
63
-
64
- <div class="form-button" @click="clickShowDialog">
65
- {{TUITranslateService.t("AIDesk.查看内容")}}
66
- </div>
55
+ <div v-if="finishSubmit || props.payload.nodeStatus == 2" class="before-form">
56
+ <div class="icon-container">
57
+ <Icon class="form-icon" :src="iconForm" width="60px" height="60px" style="margin:5px 4px"/>
58
+ <Icon v-if="finishSubmit || props.payload.nodeStatus == 2" class="form-icon-check" width="26px" height="26px" :src="iconFormFilled"/>
59
+ </div>
60
+ <div class="form-button" @click="clickShowDialog">
61
+ {{ TUITranslateService.t("AIDesk.查看内容") }}
62
+ </div>
67
63
  </div>
68
64
  </div>
69
-
70
65
  </template>
71
66
  <script lang="ts">
72
67
  import vue from '../../../../../../../adapter-vue';
@@ -81,27 +76,27 @@ import LabelMobile from './component-mobile/label-mobile.vue';
81
76
  import FormPopup from './component-mobile/form-popup.vue';
82
77
  import { CUSTOM_MESSAGE_SRC } from '../../../../../../../constant';
83
78
  import {TUITranslateService} from '@tencentcloud/chat-uikit-engine';
84
- const { ref , onMounted,computed} = vue;
79
+ const { ref, onMounted } = vue;
85
80
  interface Props {
86
81
  payload: customerServicePayloadType;
87
82
  }
88
83
  export default {
89
- components:{
90
- Icon,
91
- InputMobile,
92
- RadioMobile,
93
- FormPopup,
94
- LabelMobile
95
- },
96
- props: {
97
- payload: {
98
- type: Object as () => customerServicePayloadType,
99
- default: () => ({}),
100
- },
101
- },
102
- options:{
103
- styleIsolation: 'apply-shared'
84
+ components:{
85
+ Icon,
86
+ InputMobile,
87
+ RadioMobile,
88
+ FormPopup,
89
+ LabelMobile
90
+ },
91
+ props: {
92
+ payload: {
93
+ type: Object as () => customerServicePayloadType,
94
+ default: () => ({}),
104
95
  },
96
+ },
97
+ options:{
98
+ styleIsolation: 'apply-shared'
99
+ },
105
100
  emits: ['sendMessage','showFormPopup'],
106
101
  setup(props: Props, { emit }) {
107
102
  const showDialog = ref<boolean>(false);
@@ -109,85 +104,86 @@ export default {
109
104
  const isSubmit = ref<boolean>(false);
110
105
  const finishSubmit = ref<boolean>(false);
111
106
  const hasNullValue = ref<boolean>(true);
112
- onMounted(()=>{
113
- let inputVariables = props.payload.content.inputVariables ?? [];
114
- for(let i=0;i<inputVariables.length;i++){
115
- const name = inputVariables[i].name;
116
- const variableValue = inputVariables[i].variableValue;
117
- mapValue.value[name]=variableValue;
118
- }
119
-
107
+ onMounted(() => {
108
+ let inputVariables = props.payload.content.inputVariables ?? [];
109
+ for (let i = 0; i < inputVariables.length; i++) {
110
+ const name = inputVariables[i].name;
111
+ const variableValue = inputVariables[i].variableValue;
112
+ mapValue.value[name]=variableValue;
113
+ }
120
114
  });
121
- const clickShowDialog = ()=>{
122
- showDialog.value = true;
123
- emit('showFormPopup',true);
115
+ const clickShowDialog = () => {
116
+ if (props.payload.nodeStatus === 1) {
117
+ return;
118
+ }
119
+ showDialog.value = true;
120
+ emit('showFormPopup',true);
124
121
  }
125
122
 
126
- const closeDialog=()=>{
127
- showDialog.value = false;
128
- emit('showFormPopup',false);
123
+ const closeDialog = () => {
124
+ showDialog.value = false;
125
+ emit('showFormPopup',false);
129
126
  }
130
127
 
131
- const checkValidator = (name:string) => {
132
- hasNullValue.value = false;
133
- if(isSubmit.value == true){
134
- if(mapValue.value[name] == null || mapValue.value[name] == ''){
135
- hasNullValue.value = true;
136
- return true;
137
-
138
- }
128
+ const checkValidator = (name: string) => {
129
+ hasNullValue.value = false;
130
+ if (isSubmit.value == true) {
131
+ if (mapValue.value[name] == null || mapValue.value[name] == '') {
132
+ hasNullValue.value = true;
133
+ return true;
139
134
  }
140
- return false;
135
+ }
136
+ return false;
141
137
  }
142
138
 
143
139
  const isValid = (name:string) => {
144
- return isSubmit.value && (mapValue.value[name] == null || mapValue.value[name] == '' || mapValue.value[name] == undefined)
140
+ return isSubmit.value && (mapValue.value[name] == null || mapValue.value[name] == '' || mapValue.value[name] == undefined);
145
141
  }
146
142
 
147
143
  const handleSendForm = (data: any) => {
148
- isSubmit.value = true;
149
- let list = props.payload.content.inputVariables;
150
- for(let i=0;i<list.length;i++){
151
- let value = mapValue.value[list[i].name];
152
- if(value !='' && value != null){
153
- list[i].variableValue = value;
154
- }else {
155
- if(list[i].isRequired === 1 && checkValidator(list[i].name)){
156
- return;
157
- }
158
- }
144
+ isSubmit.value = true;
145
+ let list = props.payload.content.inputVariables;
146
+ for (let i = 0; i < list.length; i++) {
147
+ let value = mapValue.value[list[i].name];
148
+ if (value !='' && value != null) {
149
+ list[i].variableValue = value;
150
+ }else {
151
+ if (list[i].isRequired === 1 && checkValidator(list[i].name)) {
152
+ return;
153
+ }
159
154
  }
160
- const submitData = {
161
- data: JSON.stringify({
162
- src: CUSTOM_MESSAGE_SRC.MULTI_FORM,
163
- content: {
164
- inputVariables: list
165
- },
166
- customerServicePlugin: 0,
155
+ }
156
+ const submitData = {
157
+ data: JSON.stringify({
158
+ src: CUSTOM_MESSAGE_SRC.MULTI_FORM,
159
+ content: {
160
+ inputVariables: list
161
+ },
162
+ customerServicePlugin: 0,
167
163
  }),
168
- };
169
- emit('sendMessage', submitData);
170
- finishSubmit.value = true;
171
- isSubmit.value = false;
164
+ };
165
+ emit('sendMessage', submitData);
166
+ finishSubmit.value = true;
167
+ isSubmit.value = false;
172
168
  };
173
- const handleInputChange = ({name,value}) =>{
174
- mapValue.value[name] = value;
169
+ const handleInputChange = ({name,value}) => {
170
+ mapValue.value[name] = value;
175
171
  }
176
172
 
177
173
  const showValue = (name:string,variableValue:string) => {
178
- if(variableValue != null && variableValue != ''){
179
- return variableValue
180
- }
181
- return mapValue.value[name];
174
+ if (variableValue != null && variableValue != '') {
175
+ return variableValue
176
+ }
177
+ return mapValue.value[name];
182
178
  }
183
179
  return {
184
- props,
185
- iconForm,
186
- iconFormFilled,
187
- showDialog,
188
- clickShowDialog,
189
- iconClose,
190
- checkValidator,
180
+ props,
181
+ iconForm,
182
+ iconFormFilled,
183
+ showDialog,
184
+ clickShowDialog,
185
+ iconClose,
186
+ checkValidator,
191
187
  finishSubmit,
192
188
  showValue,
193
189
  mapValue,
@@ -204,6 +200,10 @@ export default {
204
200
  <style lang="scss">
205
201
  @import "../styles/common.scss";
206
202
 
203
+ .form-mobile-container {
204
+ font-family: PingFangSC-Regular;
205
+ }
206
+
207
207
  .edit-profile-container {
208
208
  @extend .container;
209
209
  font-size: 14px;
@@ -311,78 +311,91 @@ export default {
311
311
  }
312
312
  }
313
313
  .before-form {
314
+ display:flex;
315
+ flex-direction: column;
316
+ justify-content: center;
317
+ .form-button {
314
318
  display:flex;
315
- flex-direction: column;
316
319
  justify-content: center;
317
- .form-button{
318
- display:flex;
319
- justify-content: center;
320
- width: 66px;
321
- padding:6px 10px;
322
- background-color: #1c66e5;
323
- color:white;
324
- border-radius:25px ;
325
- }
326
- .icon-container{
327
- position:relative;
328
- .form-icon-check{
329
- position:absolute;
330
- right:15px;
331
- bottom:6px;
332
- }
320
+ padding:6px 10px;
321
+ background-color: #1c66e5;
322
+ color:white;
323
+ border-radius:20px;
324
+ }
325
+ .form-button-disable {
326
+ background-color: #dbdbdb;
327
+ display: flex;
328
+ justify-content: center;
329
+ padding: 6px 10px;
330
+ color: white;
331
+ border-radius: 20px;
332
+ }
333
+ .icon-container {
334
+ position: relative;
335
+ .form-icon-check {
336
+ position: absolute;
337
+ right: 15px;
338
+ bottom: 6px;
333
339
  }
340
+ }
334
341
  }
335
342
 
336
343
  .edit-form {
337
- flex:1;
338
- @include flex(column,flex-start,stretch);
339
- .edit-form-item{
340
- @include flex(row, flex-start, center);
341
- // min-height: 54px;
342
- .form-item{
343
- @include flex(row, flex-start, stretch);
344
- flex: none;
345
- .form-item-input {
346
- padding: 14px 10px;
347
- font-size: 16px;
348
- border: 0px;
349
- background-color: rgba(248, 248, 248, 1);
350
- }
351
- }
344
+ flex:1;
345
+ @include flex(column,flex-start,stretch);
346
+ .edit-form-item {
347
+ @include flex(row, flex-start, center);
348
+ .form-item {
349
+ @include flex(row, flex-start, stretch);
350
+ flex: none;
351
+ .form-item-input {
352
+ padding: 14px 10px;
353
+ font-size: 16px;
354
+ border: 0px;
355
+ background-color: rgba(248, 248, 248, 1);
356
+ }
352
357
  }
353
-
358
+ }
354
359
  }
355
360
 
356
- .dialog-title{
357
- display:flex;
358
- flex-direction: row;
359
- justify-content: space-between;
360
- padding:20px;
361
- font-size:16px;
362
- font-weight: 500;
363
- .dialog-close{
364
- color:rgba(153,153,153,1);
365
- }
361
+ .dialog-title {
362
+ display: flex;
363
+ flex-direction: row;
364
+ justify-content: space-between;
365
+ padding: 20px;
366
+ font-size: 16px;
367
+ font-weight: 500;
368
+ .dialog-close {
369
+ color: rgba(153,153,153,1);
370
+ }
366
371
  }
367
- .variable-value-container-mobile{
368
- padding:16px;
369
- display:flex;
370
- flex-direction: row;
371
- align-items: center;
372
- border-bottom:1px solid #e7e7e7;
372
+ .variable-value-container-mobile {
373
+ padding: 16px;
374
+ display: flex;
375
+ flex-direction: row;
376
+ align-items: center;
377
+ border-bottom: 1px solid #e7e7e7;
378
+ gap: 5px;
373
379
  }
374
- .button-container{
375
- display:flex;
380
+ .variable-value-label {
381
+ width: 70px;
382
+ white-space: nowrap;
383
+ }
384
+ .variable-value {
385
+ flex: 1;
386
+ }
387
+ .button-container {
388
+ display: flex;
389
+ justify-content: center;
390
+ margin: 15px;
391
+ .button {
392
+ display: flex;
376
393
  justify-content: center;
377
- margin:15px;
378
- .button {
379
- display:flex;
380
- justify-content: center;
381
- width: 87px;
382
- padding:6px 10px;
383
- background-color: #1c66e5;
384
- color:white;
385
- border-radius:25px ;
386
- }
394
+ width: 87px;
395
+ padding: 6px 10px;
396
+ background-color: #1c66e5;
397
+ color: white;
398
+ border-radius: 20px;
399
+ }
387
400
  }
388
- </style>
401
+ </style>