index.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <template>
  2. <view class="message_list">
  3. <template v-for="(item, i) in newList" :key="i">
  4. <!-- 时间 -->
  5. <view class="message__item message_item__tips" v-if="handleTime(i, list)">
  6. <view class="message__item-time">
  7. <text>{{ handleTime(i, list) }}</text>
  8. </view>
  9. </view>
  10. <!-- 系统关闭提示信息 -->
  11. <view
  12. class="message__item message_item__tips"
  13. v-if="item.msg.type == 'service_close'"
  14. >
  15. <view class="message__item-time">
  16. <text>{{ $t("会话已关闭") }}</text>
  17. </view>
  18. </view>
  19. <view
  20. class="message__item message_item__tips"
  21. v-else-if="item.msg.type == 'service_start'"
  22. >
  23. <TipsListCard :datas="item.msg.data"></TipsListCard>
  24. </view>
  25. <view
  26. class="message__item message_item__tips"
  27. v-else-if="item.msg.type == 'notice_start'"
  28. >
  29. <QuestionCard :datas="item.msg.data"></QuestionCard>
  30. </view>
  31. <!-- 意向商品 -->
  32. <!-- <view v-else-if="item.msg.type == 'need'">
  33. <PurposeCard :datas="item.msg.data"></PurposeCard>
  34. </view> -->
  35. <view
  36. class="message__item"
  37. :class="[item.send > 0 ? 'message__item-self' : '']"
  38. v-else
  39. >
  40. <!-- 头像 -->
  41. <view class="message__item-left">
  42. <image
  43. v-if="item.send > 0"
  44. class="message__item-avatar"
  45. :src="item.uimg || getuserInfo.userimg"
  46. mode=""
  47. >
  48. </image>
  49. <image
  50. v-else
  51. class="message__item-avatar"
  52. :src="item.simg"
  53. mode=""
  54. ></image>
  55. </view>
  56. <!-- 内容 -->
  57. <!-- 意向商品 -->
  58. <view v-if="item.msg.type == 'need'" class="purpose__item-right">
  59. <PurposeCard :datas="item.msg.data"></PurposeCard>
  60. </view>
  61. <view class="message__item-right" v-else>
  62. <!-- 图片 -->
  63. <view v-if="item.msg.type == 'image'">
  64. <up-image
  65. :show-loading="true"
  66. :src="item.msg.url"
  67. width="240rpx"
  68. height="240rpx"
  69. :fade="false"
  70. @click="previewImage(1, [item.msg.url])"
  71. ></up-image>
  72. </view>
  73. <!-- 欢迎信息 -->
  74. <view
  75. style="padding: 20rpx 30rpx"
  76. v-else-if="item.msg.type == 'service_welcome'"
  77. >
  78. <text>{{ item.msg.body }}</text>
  79. </view>
  80. <!-- 文本 -->
  81. <view style="padding: 20rpx 30rpx" v-else>
  82. <text>{{ item.msg.text || "" }}</text>
  83. </view>
  84. </view>
  85. <view class="message__item-status">
  86. <up-loading-icon
  87. mode="circle"
  88. size="40rpx"
  89. v-if="item.loading"
  90. ></up-loading-icon>
  91. </view>
  92. </view>
  93. </template>
  94. </view>
  95. </template>
  96. <script setup>
  97. import { computed } from "vue";
  98. import TipsListCard from "./components/tipsListCard.vue";
  99. import QuestionCard from "./components/questionCard.vue";
  100. import PurposeCard from "./components/purposeCard.vue";
  101. import useTools from "./hooks/useTools";
  102. import { storeToRefs } from "pinia";
  103. import { useUserStore } from "@/store";
  104. const useUser = useUserStore();
  105. const { getuserInfo } = storeToRefs(useUser);
  106. const { handleTime } = useTools();
  107. const props = defineProps({
  108. list: {
  109. type: Array,
  110. default: () => [],
  111. },
  112. });
  113. const newList = computed(() =>
  114. parseMessageJSON(props.list).sort((a, b) => a.id - b.id)
  115. );
  116. function parseMessageJSON(messages) {
  117. return messages.map((message) => {
  118. try {
  119. const parsedMessage = { ...message };
  120. if (typeof parsedMessage.msg === "string") {
  121. parsedMessage.msg = JSON.parse(parsedMessage.msg);
  122. }
  123. return parsedMessage;
  124. } catch (error) {
  125. return message;
  126. }
  127. });
  128. }
  129. function previewImage(index, urls) {
  130. uni.previewImage({
  131. current: index,
  132. urls: urls,
  133. success() {},
  134. });
  135. }
  136. </script>
  137. <style lang="less" scoped>
  138. @import url("@/style.less");
  139. .message_list {
  140. margin-top: 30rpx;
  141. padding: 20rpx 30rpx 30rpx;
  142. .message__item {
  143. width: 100%;
  144. display: flex;
  145. align-items: flex-start;
  146. margin-bottom: 30rpx;
  147. }
  148. .message__item-self {
  149. display: flex;
  150. flex-direction: row-reverse;
  151. .message__item-right {
  152. margin-left: 0;
  153. margin-right: 16rpx;
  154. background-color: var(--black);
  155. color: #fff;
  156. }
  157. .message__item-status {
  158. margin-left: 0;
  159. margin-right: 12rpx;
  160. }
  161. }
  162. .message_item__tips {
  163. justify-content: center;
  164. margin-bottom: 24rpx;
  165. font-size: 24rpx;
  166. color: #767676;
  167. }
  168. .message__item-avatar {
  169. width: 80rpx;
  170. height: 80rpx;
  171. border-radius: 50%;
  172. }
  173. .message__item-right {
  174. overflow: hidden;
  175. max-width: calc(100% - (80rpx * 2) - 16rpx - 20rpx - 40rpx - 12rpx);
  176. margin-left: 16rpx;
  177. border-radius: 20rpx;
  178. background: #fafafa;
  179. // text-align: justify;
  180. // word-break: break-all;
  181. word-wrap: break-word;
  182. color: #3d3d3d;
  183. font-size: 28rpx;
  184. }
  185. .message__item-status {
  186. width: 40rpx;
  187. height: 40rpx;
  188. margin-left: 12rpx;
  189. }
  190. .purpose__item-right {
  191. overflow: hidden;
  192. width: 100%;
  193. margin-right: 16rpx;
  194. border-radius: 20rpx;
  195. background: #fafafa;
  196. word-wrap: break-word;
  197. color: #3d3d3d;
  198. font-size: 28rpx;
  199. }
  200. }
  201. </style>