@tencentcloud/ai-desk-customer-vue 1.5.3 → 1.5.5

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 (51) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/assets/language_arrow_down.svg +3 -0
  3. package/assets/language_check.svg +3 -0
  4. package/components/CustomerServiceChat/chat-header/index-web.vue +215 -13
  5. package/components/CustomerServiceChat/index-web.vue +86 -25
  6. package/components/CustomerServiceChat/message-input-toolbar/file-upload/index.vue +14 -4
  7. package/components/CustomerServiceChat/message-input-toolbar/image-upload/index.vue +19 -16
  8. package/components/CustomerServiceChat/message-input-toolbar/index-web.vue +4 -4
  9. package/components/CustomerServiceChat/message-input-toolbar/video-upload/index.vue +10 -3
  10. package/components/CustomerServiceChat/message-list/index-web.vue +27 -14
  11. package/components/CustomerServiceChat/message-list/message-elements/message-bubble-web.vue +1 -0
  12. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-desk.vue +6 -1
  13. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-branch/branch-pc.vue +20 -13
  14. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-branch/index.vue +7 -6
  15. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-mobile.vue +8 -9
  16. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-pc.vue +4 -7
  17. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/index.vue +6 -12
  18. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-rating/message-rating-star.vue +25 -9
  19. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-robot-welcome.vue +74 -29
  20. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-transfer-with-desc.vue +46 -0
  21. package/components/CustomerServiceChat/message-toolbar-button/index.vue +13 -2
  22. package/components/CustomerServiceChat/style/web.scss +2 -0
  23. package/constant.ts +21 -1
  24. package/interface.ts +15 -2
  25. package/locales/en/aidesk.ts +4 -4
  26. package/locales/en/index.ts +2 -2
  27. package/locales/en/time.ts +2 -2
  28. package/locales/fil/index.ts +2 -2
  29. package/locales/fil/time.ts +2 -2
  30. package/locales/id/index.ts +2 -2
  31. package/locales/id/time.ts +2 -2
  32. package/locales/ja/index.ts +2 -2
  33. package/locales/ja/time.ts +2 -2
  34. package/locales/ms/index.ts +2 -2
  35. package/locales/ms/time.ts +2 -2
  36. package/locales/ru/index.ts +2 -2
  37. package/locales/ru/time.ts +2 -2
  38. package/locales/th/index.ts +2 -2
  39. package/locales/th/time.ts +2 -2
  40. package/locales/vi/index.ts +2 -2
  41. package/locales/vi/time.ts +2 -2
  42. package/locales/zh_cn/aidesk.ts +1 -1
  43. package/locales/zh_cn/index.ts +2 -2
  44. package/locales/zh_cn/time.ts +2 -2
  45. package/locales/zh_tw/aidesk.ts +1 -1
  46. package/locales/zh_tw/index.ts +2 -2
  47. package/locales/zh_tw/time.ts +2 -2
  48. package/package.json +2 -1
  49. package/server.ts +21 -3
  50. package/utils/index.ts +6 -13
  51. package/utils/utils.ts +44 -3
@@ -10,7 +10,7 @@
10
10
  <div :class="['video-upload', !isPC && 'video-upload-h5']">
11
11
  <input
12
12
  ref="inputRef"
13
- :title="TUITranslateService.t('视频')"
13
+ :title="props.title || TUITranslateService.t('视频')"
14
14
  type="file"
15
15
  data-type="video"
16
16
  accept="video/*"
@@ -47,6 +47,9 @@ const props = defineProps({
47
47
  type: String,
48
48
  default: 'album',
49
49
  },
50
+ title: {
51
+ type: String,
52
+ },
50
53
  });
51
54
 
52
55
  const inputRef = ref();
@@ -63,7 +66,7 @@ const handleIcon = (): string => {
63
66
  };
64
67
 
65
68
  const handleTitle = (): string => {
66
- return TUITranslateService.t('视频');
69
+ return props.title || TUITranslateService.t('视频');
67
70
  };
68
71
 
69
72
  const onIconClick = () => {
@@ -74,7 +77,11 @@ const sendVideoInWeb = (e: any) => {
74
77
  if (e?.target?.files?.length <= 0) {
75
78
  return;
76
79
  }
77
- sendVideoMessage(e?.target);
80
+ const file = e?.target?.files[0];
81
+ if (!file || !file.size) {
82
+ return;
83
+ }
84
+ sendVideoMessage(e.target);
78
85
  e.target.value = '';
79
86
  };
80
87
 
@@ -227,7 +227,7 @@ import {
227
227
  deepCopy,
228
228
  isNonEmptyObject,
229
229
  } from '../../../utils/utils';
230
- import { isMessageInvisible, isThinkingMessage, isThinkingMessageOverTime, JSONToObject } from '../../../utils/index';
230
+ import { isMessageInvisible, isThinkingMessage, isThinkingMessageOverTime, JSONToObject, isTransferMessageWithoutDesc } from '../../../utils/index';
231
231
  import { isCustomerConversation } from '../../../index';
232
232
  import { CUSTOM_MESSAGE_SRC } from '../../../constant';
233
233
  import { QuickOrderModel } from '../../../interface';
@@ -352,21 +352,31 @@ onUnmounted(() => {
352
352
 
353
353
  function onNewMessageList(list: IMessageModel[]) {
354
354
  list.forEach((message:IMessageModel) => {
355
- if (message?.type === TUIChatEngine.TYPES.MSG_CUSTOM) {
356
- const data = JSONToObject(message?.payload?.data);
357
- if (data?.src === CUSTOM_MESSAGE_SRC.SEAT_STATUS) {
358
- if (data?.content.command === "updateSeatStatus") {
359
- if (data.content.content === 'inSeat') {
360
- TUIStore.update(StoreName.CUSTOM, "isInHumanService", true);
361
- } else if (data.content.content === 'outSeat') {
355
+ if (message.type === TUIChatEngine.TYPES.MSG_CUSTOM) {
356
+ const data = JSONToObject(message.payload.data);
357
+ if (data) {
358
+ if (data.src === CUSTOM_MESSAGE_SRC.BOT_STATUS) {
359
+ if (data.content.content === 'inBot') {
362
360
  TUIStore.update(StoreName.CUSTOM, "isInHumanService", false);
363
361
  }
364
- }
365
- } else if (data?.src === CUSTOM_MESSAGE_SRC.TYPING_STATE) {
366
- if (data?.typingStatus === 1) {
367
- TUIStore.update(StoreName.CUSTOM, 'isTyping', true);
368
- } else {
369
- TUIStore.update(StoreName.CUSTOM, 'isTyping', false);
362
+ } else if (data.src === CUSTOM_MESSAGE_SRC.SEAT_STATUS) {
363
+ if (data.content.command === "updateSeatStatus") {
364
+ if (data.content.content === 'inSeat') {
365
+ TUIStore.update(StoreName.CUSTOM, "isInHumanService", true);
366
+ } else if (data.content.content === 'outSeat') {
367
+ TUIStore.update(StoreName.CUSTOM, "isInHumanService", false);
368
+ }
369
+ }
370
+ } else if (data.src === CUSTOM_MESSAGE_SRC.TYPING_STATE) {
371
+ if (data.typingStatus === 1) {
372
+ TUIStore.update(StoreName.CUSTOM, 'isTyping', true);
373
+ } else {
374
+ TUIStore.update(StoreName.CUSTOM, 'isTyping', false);
375
+ }
376
+ } else if (data.src === CUSTOM_MESSAGE_SRC.NO_SEAT_ONLINE || data.src === CUSTOM_MESSAGE_SRC.TIMEOUT || data.src === CUSTOM_MESSAGE_SRC.END) {
377
+ TUIStore.update(StoreName.CUSTOM, "isInSession", false);
378
+ } else if (data.src === CUSTOM_MESSAGE_SRC.SESSION_RESTARTED) {
379
+ TUIStore.update(StoreName.CUSTOM, "isInSession", true);
370
380
  }
371
381
  }
372
382
  }
@@ -391,6 +401,9 @@ async function onMessageListUpdated(list: IMessageModel[]) {
391
401
  if (isThinkingMessage(message)) {
392
402
  return isThinkingMessageOverTime(message);
393
403
  }
404
+ if (isTransferMessageWithoutDesc(message)) {
405
+ return false;
406
+ }
394
407
  return !message.isDeleted && !isMessageInvisible(message as any);
395
408
  });
396
409
 
@@ -382,6 +382,7 @@ function setStatus(status: ReadState) {
382
382
  }
383
383
 
384
384
  .message-body-nick-name {
385
+ font-family: PingFangSC-Regular;
385
386
  display: block;
386
387
  margin-bottom: 4px;
387
388
  font-size: 12px;
@@ -71,7 +71,10 @@
71
71
  <div v-if="payload.src === CUSTOM_MESSAGE_SRC.ORDER">
72
72
  <MessageOrder :payload="payload" />
73
73
  </div>
74
- </div>
74
+ <div v-if="payload.src === CUSTOM_MESSAGE_SRC.TRANSFER_TO_HUMAN || payload.src === CUSTOM_MESSAGE_SRC.TRANSFER_TO_TASK_FLOW">
75
+ <MessageTransferWithDesc :payload="payload" />
76
+ </div>
77
+ </div>
75
78
  </div>
76
79
  </template>
77
80
  <script lang="ts">
@@ -91,6 +94,7 @@ import MessageMultiBranch from './message-multi-branch/index.vue';
91
94
  import MessageMultiForm from './message-multi-form/index.vue';
92
95
  import MessageConcurrencyLimit from "./message-concurrency-limit.vue";
93
96
  import MessageOrder from './message-order.vue';
97
+ import MessageTransferWithDesc from './message-transfer-with-desc.vue';
94
98
  import {
95
99
  IMessageModel,
96
100
  TUIChatService,
@@ -112,6 +116,7 @@ export default {
112
116
  MessageRating,
113
117
  MessageConcurrencyLimit,
114
118
  MessageOrder,
119
+ MessageTransferWithDesc
115
120
  },
116
121
  props: {
117
122
  message: {
@@ -23,10 +23,12 @@ import vue from '../../../../../../../adapter-vue';
23
23
  import { TUITranslateService } from '@tencentcloud/chat-uikit-engine';
24
24
  import { customerServicePayloadType } from '../../../../../../../interface';
25
25
  import { isPC } from '../../../../../../../utils/env'
26
+ import { openSafeUrl } from '../../../../../../../utils/utils';
26
27
  const { ref } = vue;
27
28
  interface branchItem {
28
29
  content: string;
29
30
  desc: string;
31
+ url?: string;
30
32
  }
31
33
 
32
34
  interface Props {
@@ -47,20 +49,25 @@ export default {
47
49
  if (!branch.content) {
48
50
  return;
49
51
  }
50
- let cloudCustomData;
51
- if (props.payload.optionType === 0) {
52
- cloudCustomData = '';
53
- canSelect.value = false;
54
- } else if (props.payload.optionType === 1) {
55
- cloudCustomData = JSON.stringify({
56
- BranchOptionInfo: {
57
- taskID: props.payload.taskInfo?.taskID,
58
- nodeID: props.payload.taskInfo?.nodeID,
59
- env: props.payload.taskInfo?.env,
60
- }
61
- });
52
+ if (branch.url) {
53
+ openSafeUrl(branch.url);
54
+ } else {
55
+ let cloudCustomData;
56
+ if (props.payload.optionType === 0) {
57
+ cloudCustomData = '';
58
+ canSelect.value = false;
59
+ } else if (props.payload.optionType === 1) {
60
+ cloudCustomData = JSON.stringify({
61
+ BranchOptionInfo: {
62
+ taskID: props.payload.taskInfo?.taskID,
63
+ nodeID: props.payload.taskInfo?.nodeID,
64
+ env: props.payload.taskInfo?.env,
65
+ }
66
+ });
67
+ }
68
+ emit('input-click', branch, cloudCustomData);
62
69
  }
63
- emit('input-click', branch, cloudCustomData);
70
+
64
71
  };
65
72
 
66
73
  return {
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="message-form">
3
3
  <BranchPc
4
- :payload ="payload"
4
+ :payload ="forwardPayload"
5
5
  @input-click="handleContentListItemClick"
6
6
  />
7
7
  </div>
@@ -11,11 +11,12 @@
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;
18
18
  desc: string;
19
+ url?: string;
19
20
  }
20
21
 
21
22
  interface Props {
@@ -34,9 +35,6 @@ export default {
34
35
  },
35
36
  emits: ['sendMessage', 'heightChanged'],
36
37
  setup(props: Props, { emit }) {
37
- const payload = computed<customerServicePayloadType>(() => {
38
- return props.payload;
39
- });
40
38
  const handleContentListItemClick = (branch: branchItem, cloudCustomData?: string) => {
41
39
  emit('sendMessage', { text: branch.content }, cloudCustomData || '');
42
40
  };
@@ -44,8 +42,11 @@ export default {
44
42
  const handleFormSaveInputSubmit = (text: string) => {
45
43
  emit('sendMessage', { text });
46
44
  };
45
+ const forwardPayload = computed(() => {
46
+ return props.payload;
47
+ });
47
48
  return {
48
- payload,
49
+ forwardPayload,
49
50
  handleContentListItemClick,
50
51
  handleFormSaveInputSubmit,
51
52
  };
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="form-mobile-container">
3
- <div v-if="!finishSubmit && props.payload.nodeStatus !== 2" class="before-form">
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="!finishSubmit && item.formType == 0 && props.payload.nodeStatus == 0">
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="!finishSubmit && item.formType == 1 && props.payload.nodeStatus == 0">
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="!finishSubmit && props.payload.nodeStatus === 0">
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="finishSubmit || props.payload.nodeStatus == 2" class="before-form">
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="finishSubmit || props.payload.nodeStatus == 2" class="form-icon-check" width="26px" height="26px" :src="iconFormFilled"/>
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;
@@ -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="finishSubmit || props.payload.nodeStatus == 2" >
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="!finishSubmit && item.formType == 0 && props.payload.nodeStatus !== 2">
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="!finishSubmit && item.formType == 1 && props.payload.nodeStatus !== 2">
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="!finishSubmit && props.payload.nodeStatus !== 2">
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="payloads" @sendMessage="handleSendForm" />
3
+ <FormPC :payload="forwardPayload" @sendMessage="handleSendForm" />
4
4
  </div>
5
5
  <div v-else>
6
- <FormMobile :payload="payloads" @sendMessage="handleSendForm" @showFormPopup="handleShowFormPopup"/>
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
- payloads,
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 :style="{ marginTop: 10 + 'px', marginBottom: 10 + 'px', wordBreak: 'normal' }">
34
- {{
35
- hoverValue === -1
36
- ? value === -1
37
- ? TUITranslateService.t("AIDesk.如果满意请给好评哦~")
38
- : desc[value]
39
- : desc[hoverValue]
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>
@@ -17,13 +17,18 @@
17
17
  <Icon :src="iconRefresh" />
18
18
  </div>
19
19
  </div>
20
- <div
21
- v-for="(item, index) in showList"
22
- :key="index"
23
- class="welcome-item"
24
- @click="handleContentListItemClick(item)"
25
- >
26
- <div>{{ item.content }}</div>
20
+ <div class="welcome-items-container">
21
+ <div
22
+ v-for="(item, index) in showList"
23
+ :key="index"
24
+ class="welcome-item"
25
+ @click="handleContentListItemClick(item)"
26
+ >
27
+ <div class="item-content">{{ item.content }}</div>
28
+ </div>
29
+ <div class="welcome-item welcome-item-hidden">
30
+ {{ longestContent }}
31
+ </div>
27
32
  </div>
28
33
  </div>
29
34
  </template>
@@ -37,7 +42,7 @@ import Icon from './customer-icon.vue';
37
42
  import iconQuestion from '../../../../../../assets/icon_question.png';
38
43
  import iconRefresh from '../../../../../../assets/icon_refresh.png';
39
44
  import { customerServicePayloadType } from '../../../../../../interface';
40
- const { reactive, toRefs } = vue;
45
+ const { reactive, toRefs, computed } = vue;
41
46
 
42
47
  interface Props {
43
48
  payload: customerServicePayloadType;
@@ -56,7 +61,7 @@ export default {
56
61
  props: {
57
62
  payload: {
58
63
  type: Object as () => customerServicePayloadType,
59
- default: () => ({ content: { title: '', items: [] } }),
64
+ default: () => ({ content: { title: '', items: [] }}),
60
65
  },
61
66
  },
62
67
  emits: ['sendMessage'],
@@ -86,6 +91,19 @@ export default {
86
91
  );
87
92
  data.pageNumber += 1;
88
93
  };
94
+
95
+ const longestContent = computed(() => {
96
+ if (!data.list) {
97
+ return '';
98
+ }
99
+ let longestContent = '';
100
+ data.list.forEach((item) => {
101
+ if (item.content.length > longestContent.length) {
102
+ longestContent = item.content;
103
+ }
104
+ });
105
+ return longestContent;
106
+ });
89
107
 
90
108
  return {
91
109
  ...toRefs(data),
@@ -96,6 +114,7 @@ export default {
96
114
  changeBranchList,
97
115
  iconQuestion,
98
116
  iconRefresh,
117
+ longestContent
99
118
  };
100
119
  },
101
120
  };
@@ -104,6 +123,9 @@ export default {
104
123
  <style lang="scss">
105
124
  .welcome-card {
106
125
  max-width: 400px;
126
+ display: flex;
127
+ flex-direction: column;
128
+ align-items: center;
107
129
 
108
130
  .welcome-title {
109
131
  display: flex;
@@ -111,6 +133,8 @@ export default {
111
133
  margin-bottom: 10px;
112
134
  justify-content: space-between;
113
135
  align-items: center;
136
+ width: 100%;
137
+ gap: 10px;
114
138
  }
115
139
 
116
140
  .welcome-title-left-container {
@@ -151,28 +175,49 @@ export default {
151
175
  cursor: pointer;
152
176
  }
153
177
 
154
- .welcome-item {
155
- padding: 6px;
178
+ .welcome-items-container {
179
+ width: 100%;
156
180
  display: flex;
157
- justify-content: center;
181
+ flex-direction: column;
158
182
  align-items: center;
159
- cursor: pointer;
160
- background-color: #ffffff;
161
- margin-bottom: 10px;
162
- border:1px solid #adcfff;
163
- border-radius: 20px;
164
- font-weight: 500;
165
- color: #1c66e5;
166
- gap: 10px;
167
- word-break: break-word;
168
- }
169
-
170
- .welcome-item:hover {
171
- background: #f2f7ff;
172
- }
173
-
174
- .welcome-item:last-child {
175
- margin-bottom: 0;
183
+ .welcome-item {
184
+ width: 100%;
185
+ padding: 6px 10px;
186
+ display: flex;
187
+ justify-content: center;
188
+ align-items: center;
189
+ cursor: pointer;
190
+ background-color: #ffffff;
191
+ margin-bottom: 10px;
192
+ border:1px solid #adcfff;
193
+ border-radius: 20px;
194
+ font-weight: 500;
195
+ color: #1c66e5;
196
+ gap: 10px;
197
+ box-sizing: border-box;
198
+ .item-content {
199
+ text-align: center;
200
+ overflow-wrap: break-word;
201
+ word-break: normal;
202
+ width: 100%;
203
+ padding: 0 10px;
204
+ }
205
+ }
206
+
207
+ .welcome-item:hover {
208
+ background: #f2f7ff;
209
+ }
210
+
211
+ .welcome-item:last-child {
212
+ margin-bottom: 0;
213
+ }
214
+
215
+ .welcome-item-hidden {
216
+ visibility: hidden;
217
+ padding: 0;
218
+ margin: 0;
219
+ height: 0;
220
+ }
176
221
  }
177
222
  }
178
223
  </style>