messages.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <template>
  2. <view class="message_list">
  3. <view class="_list" v-for="item, index in newList" :key="index">
  4. <!-- 时间 -->
  5. <view class="_time" v-if="handleTime(index, newList)">
  6. <text>{{ handleTime(index, newList) }}</text>
  7. </view>
  8. <view class="_list_Y" v-if="!item.send">
  9. <view class="Y_left">
  10. <image lazy-load :src="item.simg || list[0].simg" class="avatar"></image>
  11. <view class="Y_cont" v-if="item.msg?.type == 'text'">{{ item.msg.text }}</view>
  12. <image :src="item.msg.url" lazy-load v-if="item.msg?.type == 'image'" class="Y_img"
  13. @click="previewImage(item.msg.url)"></image>
  14. </view>
  15. </view>
  16. <view class="_list_M" v-if="item.send">
  17. <view class="M_right">
  18. <view class="M_status">
  19. <up-loading-icon mode="circle" size="40rpx" v-if="item.loading"></up-loading-icon>
  20. </view>
  21. <view class="M_cont" v-if="item.msg?.type == 'text'">{{ item.msg.text }}</view>
  22. <image :src="item.msg.url" lazy-load v-if="item.msg?.type == 'image'" class="M_img"
  23. @click="previewImage(item.msg.url)"></image>
  24. <image :src="item.uimg || userInfo.userimg" lazy-load class="avatar"></image>
  25. </view>
  26. </view>
  27. </view>
  28. </view>
  29. </template>
  30. <script setup>
  31. import { computed } from "vue"
  32. import { useUserStore } from "@/store"
  33. import useTools from "@/pages/user/user_chat/hooks/useTools"
  34. const useUser = useUserStore();
  35. const userInfo = computed(() => useUser.getuserInfo)
  36. const { handleTime } = useTools();
  37. const props = defineProps({
  38. list: {
  39. type: Array,
  40. default: []
  41. },
  42. })
  43. const newList = computed(() => parseMessageJSON(props.list).sort((a, b) => a.id - b.id))
  44. function parseMessageJSON(messages) {
  45. return messages.map(message => {
  46. try {
  47. const parsedMessage = { ...message };
  48. if (typeof parsedMessage.msg === 'string') {
  49. parsedMessage.msg = JSON.parse(parsedMessage.msg);
  50. }
  51. return parsedMessage;
  52. } catch (error) {
  53. return message;
  54. }
  55. });
  56. }
  57. const previewImage = (url) => {
  58. uni.previewImage({
  59. urls: [url]
  60. })
  61. }
  62. </script>
  63. <style lang="less" scoped>
  64. @import url('@/style.less');
  65. .message_list {
  66. ._list {
  67. margin-top: 30rpx;
  68. .loading_icon {
  69. width: 100rpx;
  70. height: 20rpx;
  71. }
  72. ._time {
  73. display: flex;
  74. justify-content: center;
  75. margin-bottom: 24rpx;
  76. font-size: 24rpx;
  77. color: #767676;
  78. }
  79. &_Y {
  80. .Y_left {
  81. display: flex;
  82. .avatar {
  83. @width: 80rpx;
  84. width: @width;
  85. height: @width;
  86. border-radius: 50%;
  87. margin-right: 12rpx;
  88. }
  89. .Y_cont {
  90. max-width: 77%;
  91. background-color: var(--inputBg);
  92. border-radius: 20rpx;
  93. box-sizing: border-box;
  94. padding: 16rpx 28rpx;
  95. line-height: 44rpx;
  96. .size(28rpx);
  97. color: var(--text);
  98. word-break: break-all;
  99. }
  100. .Y_img {
  101. width: 240rpx;
  102. height: 240rpx;
  103. border-radius: 20rpx;
  104. }
  105. }
  106. }
  107. &_M {
  108. .M_right {
  109. display: flex;
  110. justify-content: flex-end;
  111. .M_status {
  112. margin-right: 12rpx;
  113. }
  114. .avatar {
  115. @width: 80rpx;
  116. width: @width;
  117. height: @width;
  118. border-radius: 50%;
  119. margin-left: 12rpx;
  120. }
  121. .M_cont {
  122. overflow: hidden;
  123. max-width: 77%;
  124. background: var(--black);
  125. border-radius: 20rpx;
  126. box-sizing: border-box;
  127. padding: 16rpx 28rpx;
  128. line-height: 44rpx;
  129. .size(28rpx);
  130. color: var(--light);
  131. word-break: break-all;
  132. }
  133. .M_img {
  134. width: 240rpx;
  135. height: 240rpx;
  136. border-radius: 20rpx;
  137. }
  138. }
  139. }
  140. }
  141. }
  142. </style>