message-abstract-custom.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <template>
  2. <!-- Custom message keyword keyword search description, so here only a few custom messages that need to display highlighted description type are parsed -->
  3. <div
  4. :class="['message-abstract-custom']"
  5. @click.capture.stop
  6. >
  7. <template v-if="businessID === CHAT_MSG_CUSTOM_TYPE.SERVICE">
  8. <div :class="['service']">
  9. <h1 :class="['service-header']">
  10. <label :class="['service-header-title']">{{ extensionJSON.title }}</label>
  11. <a
  12. v-if="extensionJSON.hyperlinks_text"
  13. :class="['service-header-link', 'link']"
  14. :href="extensionJSON.hyperlinks_text.value"
  15. target="view_window"
  16. >
  17. {{ extensionJSON.hyperlinks_text.key }}
  18. </a>
  19. </h1>
  20. <ul
  21. v-if="extensionJSON.item && extensionJSON.item.length > 0"
  22. :class="['service-list']"
  23. >
  24. <li
  25. v-for="(item, index) in extensionJSON.item"
  26. :key="index"
  27. :class="['service-list-item']"
  28. >
  29. <a
  30. v-if="isUrl(item.value)"
  31. :class="['service-list-item-link', 'link']"
  32. :href="item.value"
  33. target="view_window"
  34. >{{ item.key }}</a>
  35. <p
  36. v-else
  37. :class="['service-list-item-key']"
  38. >
  39. {{ item.key }}
  40. </p>
  41. </li>
  42. </ul>
  43. <div :class="['service-description', 'description']">
  44. <span
  45. v-for="(contentItem, index) in descriptionForShow"
  46. :key="index"
  47. :class="[(contentItem && contentItem.isHighlight) ? 'highlight' : 'normal']"
  48. >
  49. {{ contentItem.text }}
  50. </span>
  51. </div>
  52. </div>
  53. </template>
  54. <template v-else-if="businessID === CHAT_MSG_CUSTOM_TYPE.EVALUATE">
  55. <div class="evaluate">
  56. <div :class="['evaluate-description', 'description']">
  57. <span
  58. v-for="(contentItem, index) in descriptionForShow"
  59. :key="index"
  60. :class="[(contentItem && contentItem.isHighlight) ? 'highlight' : 'normal']"
  61. >
  62. {{ contentItem.text }}
  63. </span>
  64. </div>
  65. <ul
  66. v-if="extensionJSON.score"
  67. class="evaluate-list"
  68. >
  69. <li
  70. v-for="(item, index) in Math.max(extensionJSON.score, 0)"
  71. :key="index"
  72. class="evaluate-list-item"
  73. >
  74. <Icon
  75. :file="star"
  76. class="file-icon"
  77. />
  78. </li>
  79. </ul>
  80. <article>{{ extensionJSON.comment }}</article>
  81. </div>
  82. </template>
  83. <template v-else-if="businessID === CHAT_MSG_CUSTOM_TYPE.ORDER">
  84. <div class="order">
  85. <img
  86. class="order-image"
  87. :src="extensionJSON.imageUrl"
  88. alt=""
  89. >
  90. <main class="order-main">
  91. <h1 class="order-main-title">
  92. {{ extensionJSON.title }}
  93. </h1>
  94. <div :class="['order-main-description', 'description']">
  95. <span
  96. v-for="(contentItem, index) in descriptionForShow"
  97. :key="index"
  98. :class="[(contentItem && contentItem.isHighlight) ? 'highlight' : 'normal']"
  99. >
  100. {{ contentItem.text }}
  101. </span>
  102. </div>
  103. <span class="order-main-price">{{ extensionJSON.price }}</span>
  104. </main>
  105. </div>
  106. </template>
  107. <template v-else-if="businessID === CHAT_MSG_CUSTOM_TYPE.LINK">
  108. <div class="text-link">
  109. <div :class="['text-link-description', 'description']">
  110. <p>{{ extensionJSON.text }}</p>
  111. </div>
  112. <a
  113. :class="['link']"
  114. :href="extensionJSON.link"
  115. target="view_window"
  116. >{{
  117. TUITranslateService.t("message.custom.查看详情>>")
  118. }}</a>
  119. </div>
  120. </template>
  121. <template v-else>
  122. <span>{{ defaultMessageContent }}</span>
  123. </template>
  124. </div>
  125. </template>
  126. <script setup lang="ts">
  127. import { TUITranslateService, IMessageModel } from '@tencentcloud/chat-uikit-engine';
  128. import { ref, computed, withDefaults } from '../../../../../adapter-vue';
  129. import { CHAT_MSG_CUSTOM_TYPE } from '../../../../../constant';
  130. import { JSONToObject, isUrl } from '../../../../../utils/index';
  131. import Icon from '../../../../common/Icon.vue';
  132. import star from '../../../../../assets/icon/star-light.png';
  133. import { IHighlightContent } from '../../../type';
  134. import { ISearchResultListItem } from '../../../../../interface';
  135. interface IProps {
  136. contentText: IHighlightContent[];
  137. message: IMessageModel | ISearchResultListItem;
  138. messageContent: Record<string, unknown> | undefined;
  139. }
  140. const props = withDefaults(defineProps<IProps>(), {
  141. contentText: () => ([]) as IHighlightContent[],
  142. message: () => ({}) as IMessageModel,
  143. messageContent: () => ({}) as Record<string, unknown>,
  144. });
  145. const custom = ref<{ data?: string; description?: string; extension?: string }>(
  146. (props?.message as IMessageModel)?.payload,
  147. );
  148. const extensionJSON = computed(() => custom?.value?.data ? JSONToObject(custom.value.data) : custom?.value?.data);
  149. const businessID = computed(() => extensionJSON?.value?.businessID);
  150. const descriptionForShow = ref<Array<{ text: string; isHighlight: boolean }>>(props?.contentText);
  151. const defaultMessageContent = ref<string>(props?.messageContent?.custom as string || '[自定义消息]');
  152. </script>
  153. <style scoped lang="scss">
  154. @import "../../../../../assets/styles/common";
  155. .message-abstract-custom {
  156. .service {
  157. .service-header {
  158. font-size: 14px;
  159. color: #000;
  160. }
  161. .service-list {
  162. .service-list-item {
  163. font-size: 14px;
  164. }
  165. }
  166. }
  167. .evaluate {
  168. .evaluate-list {
  169. padding: 5px 0;
  170. display: flex;
  171. flex-direction: row;
  172. .evaluate-item {
  173. padding: 0 2px;
  174. }
  175. }
  176. }
  177. .order {
  178. display: flex;
  179. .order-main {
  180. padding-left: 5px;
  181. .order-main-title {
  182. font-size: 14px;
  183. color: #000;
  184. }
  185. .order-main-description {
  186. font-family: PingFangSC-Regular, sans-serif;
  187. width: 145px;
  188. line-height: 17px;
  189. font-size: 14px;
  190. color: #999;
  191. letter-spacing: 0;
  192. margin-bottom: 6px;
  193. word-break: break-word;
  194. }
  195. .order-main-price {
  196. font-family: PingFangSC-Regular, sans-serif;
  197. line-height: 25px;
  198. color: #ff7201;
  199. }
  200. }
  201. .order-img {
  202. width: 67px;
  203. height: 67px;
  204. }
  205. }
  206. .link {
  207. font-size: 14px;
  208. color: #679ce1;
  209. }
  210. .description {
  211. font-size: 14px;
  212. color: #000;
  213. .highlight {
  214. background-color: #007aff33;
  215. }
  216. .normal {
  217. font-size: 14px;
  218. color: #000;
  219. }
  220. }
  221. }
  222. </style>