message-abstract-file.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <template>
  2. <div :class="['message-abstract-file', `message-abstract-file-${displayType}`]">
  3. <div :class="['message-abstract-file-left']">
  4. <img
  5. :class="['message-abstract-file-left-icon']"
  6. :src="typeIcon.iconSrc"
  7. >
  8. </div>
  9. <div :class="['message-abstract-file-main']">
  10. <div :class="['message-abstract-file-main-name']">
  11. <span
  12. v-for="(contentItem, index) in contentText"
  13. :key="index"
  14. :class="[(contentItem && contentItem.isHighlight) ? 'highlight' : 'normal']"
  15. >
  16. {{ contentItem.text }}
  17. </span>
  18. </div>
  19. <div :class="['message-abstract-file-main-size']">
  20. {{ fileSize }}
  21. </div>
  22. </div>
  23. </div>
  24. </template>
  25. <script setup lang="ts">
  26. import { ref, computed, withDefaults } from '../../../../../adapter-vue';
  27. import { IHighlightContent } from '../../../type';
  28. interface IProps {
  29. contentText: Array<IHighlightContent>;
  30. messageContent: Record<string, unknown> | undefined;
  31. displayType: 'bubble' | 'info';
  32. }
  33. const props = withDefaults(defineProps<IProps>(), {
  34. contentText: () => ([]) as Array<IHighlightContent>,
  35. messageContent: () => ({}) as Record<string, unknown>,
  36. displayType: 'bubble',
  37. });
  38. const contentText = ref<Array<{ text: string; isHighlight: boolean }>>(props.contentText);
  39. const typeIcon = computed(() => {
  40. const fileUrl = props?.messageContent?.url as string;
  41. const index = fileUrl?.lastIndexOf('.');
  42. const type = fileUrl?.substring(index + 1);
  43. return handleFileIconForShow(type);
  44. });
  45. const fileSize = computed(() => props?.messageContent?.size);
  46. const handleFileIconForShow = (type: string) => {
  47. const urlBase = 'https://web.sdk.qcloud.com/component/TUIKit/assets/file-';
  48. const fileTypes = [
  49. 'image',
  50. 'pdf',
  51. 'text',
  52. 'ppt',
  53. 'presentation',
  54. 'sheet',
  55. 'zip',
  56. 'word',
  57. 'video',
  58. 'unknown',
  59. ];
  60. let url = '';
  61. let iconType = '';
  62. fileTypes?.forEach((typeName: string) => {
  63. if (type?.includes(typeName)) {
  64. url = urlBase + typeName + '.svg';
  65. iconType = typeName;
  66. }
  67. });
  68. return {
  69. iconSrc: url ? url : urlBase + 'unknown.svg',
  70. iconType: iconType ? iconType : 'unknown',
  71. };
  72. };
  73. </script>
  74. <style scoped lang="scss">
  75. @import "../../../../../assets/styles/common";
  76. .message-abstract-file {
  77. display: flex;
  78. flex: 1;
  79. overflow: hidden;
  80. flex-direction: row;
  81. justify-content: center;
  82. align-items: center;
  83. &-left {
  84. width: 42px;
  85. height: 32px;
  86. &-icon {
  87. width: 32px;
  88. height: 32px;
  89. margin-right: 10px;
  90. border-radius: 5px;
  91. }
  92. }
  93. &-main {
  94. flex: 1;
  95. overflow: hidden;
  96. &-name {
  97. width: 100%;
  98. color: #000;
  99. font-size: 14px;
  100. height: 20px;
  101. overflow: hidden;
  102. text-overflow: ellipsis;
  103. white-space: nowrap;
  104. .highlight {
  105. background-color: #007aff33;
  106. }
  107. .normal {
  108. color: #000;
  109. }
  110. }
  111. &-size {
  112. overflow: hidden;
  113. text-overflow: ellipsis;
  114. white-space: nowrap;
  115. color: #888;
  116. font-size: 12px;
  117. }
  118. }
  119. &-bubble {
  120. background-color: #f1f1f1;
  121. .message-abstract-file-main {
  122. .message-abstract-file-main-name {
  123. color: #1f2329;
  124. .normal {
  125. color: #1f2329;
  126. }
  127. }
  128. }
  129. }
  130. &-file {
  131. margin: 8px 10px 5px;
  132. padding: 10px;
  133. background-color: #f1f1f1;
  134. height: 51px;
  135. }
  136. }
  137. </style>