Bläddra i källkod

【优化】:mall 客服优化消息样式,增加消息时间段显示

puhui999 11 månader sedan
förälder
incheckning
893cd5d8f5

+ 77 - 29
src/views/mall/promotion/kefu/components/KeFuChatBox.vue

@@ -6,34 +6,55 @@
     <el-main class="kefu-content" style="overflow: visible">
       <el-scrollbar ref="scrollbarRef" always height="calc(100vh - 495px)">
         <div ref="innerRef" class="w-[100%] pb-3px">
-          <div
-            v-for="item in messageList"
-            :key="item.id"
-            :class="[
-              item.senderType === UserTypeEnum.MEMBER
-                ? `ss-row-left`
-                : item.senderType === UserTypeEnum.ADMIN
-                  ? `ss-row-right`
-                  : ''
-            ]"
-            class="flex mb-20px w-[100%]"
-          >
-            <el-avatar
-              v-if="item.senderType === UserTypeEnum.MEMBER"
-              :src="keFuConversation.userAvatar"
-              alt="avatar"
-            />
-            <div class="kefu-message p-10px">
-              <!-- 文本消息 -->
-              <TextMessageItem :message="item" />
-              <!-- 图片消息 -->
-              <ImageMessageItem :message="item" />
+          <div v-for="(item, index) in messageList" :key="item.id" class="w-[100%]">
+            <div class="flex justify-center items-center mb-20px">
+              <!-- 日期 -->
+              <div
+                v-if="
+                  item.contentType !== KeFuMessageContentTypeEnum.SYSTEM && showTime(item, index)
+                "
+                class="date-message"
+              >
+                {{ formatDate(item.createTime) }}
+              </div>
+              <!-- 系统消息 -->
+              <view
+                v-if="item.contentType === KeFuMessageContentTypeEnum.SYSTEM"
+                class="system-message"
+              >
+                {{ item.content }}
+              </view>
+            </div>
+            <div
+              :class="[
+                item.senderType === UserTypeEnum.MEMBER
+                  ? `ss-row-left`
+                  : item.senderType === UserTypeEnum.ADMIN
+                    ? `ss-row-right`
+                    : ''
+              ]"
+              class="flex mb-20px w-[100%]"
+            >
+              <el-avatar
+                v-if="item.senderType === UserTypeEnum.MEMBER"
+                :src="keFuConversation.userAvatar"
+                alt="avatar"
+              />
+              <div
+                :class="{ 'kefu-message': KeFuMessageContentTypeEnum.TEXT === item.contentType }"
+                class="p-10px"
+              >
+                <!-- 文本消息 -->
+                <TextMessageItem :message="item" />
+                <!-- 图片消息 -->
+                <ImageMessageItem :message="item" />
+              </div>
+              <el-avatar
+                v-if="item.senderType === UserTypeEnum.ADMIN"
+                :src="item.senderAvatar"
+                alt="avatar"
+              />
             </div>
-            <el-avatar
-              v-if="item.senderType === UserTypeEnum.ADMIN"
-              :src="item.senderAvatar"
-              alt="avatar"
-            />
           </div>
         </div>
       </el-scrollbar>
@@ -69,6 +90,11 @@ import { Emoji } from './tools/emoji'
 import { KeFuMessageContentTypeEnum } from './tools/constants'
 import { isEmpty } from '@/utils/is'
 import { UserTypeEnum } from '@/utils/constants'
+import { formatDate } from '@/utils/formatTime'
+import dayjs from 'dayjs'
+import relativeTime from 'dayjs/plugin/relativeTime'
+
+dayjs.extend(relativeTime)
 
 defineOptions({ name: 'KeFuMessageBox' })
 const messageTool = useMessage()
@@ -90,7 +116,7 @@ const getMessageList = async (conversation: KeFuConversationRespVO) => {
   if (!poller.value) {
     poller.value = setInterval(() => {
       getMessageList(conversation)
-    }, 1000)
+    }, 2000)
   }
 }
 defineExpose({ getMessageList })
@@ -143,7 +169,18 @@ const scrollToBottom = async () => {
   await nextTick()
   scrollbarRef.value!.setScrollTop(innerRef.value!.clientHeight)
 }
-
+/**
+ * 是否显示时间
+ * @param {*} item - 数据
+ * @param {*} index - 索引
+ */
+const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => {
+  if (unref(messageList.value)[index + 1]) {
+    let dateString = dayjs(unref(messageList.value)[index + 1].createTime).fromNow()
+    return dateString !== dayjs(unref(item).createTime).fromNow()
+  }
+  return false
+})
 // TODO puhui999: 轮训相关,功能完善后移除
 onBeforeUnmount(() => {
   if (!poller.value) {
@@ -225,6 +262,17 @@ onBeforeUnmount(() => {
         transform: scale(1.03);
       }
     }
+
+    .date-message,
+    .system-message {
+      width: fit-content;
+      border-radius: 12rpx;
+      padding: 8rpx 16rpx;
+      margin-bottom: 16rpx;
+      background-color: #e8e8e8;
+      color: #999;
+      font-size: 24rpx;
+    }
   }
 
   .chat-tools {

+ 1 - 19
src/views/mall/promotion/kefu/components/KeFuConversationBox.vue

@@ -36,7 +36,7 @@
 <script lang="ts" setup>
 import { KeFuConversationApi, KeFuConversationRespVO } from '@/api/mall/promotion/kefu/conversation'
 import { useEmoji } from './tools/emoji'
-import { formatDate, getNowDateTime } from '@/utils/formatTime'
+import { formatDate } from '@/utils/formatTime'
 import { KeFuMessageContentTypeEnum } from './tools/constants'
 
 defineOptions({ name: 'KeFuConversationBox' })
@@ -45,24 +45,6 @@ const activeConversationIndex = ref(-1) // 选中的会话
 const conversationList = ref<KeFuConversationRespVO[]>([]) // 会话列表
 const getConversationList = async () => {
   conversationList.value = await KeFuConversationApi.getConversationList()
-  // 测试数据
-  for (let i = 0; i < 5; i++) {
-    conversationList.value.push({
-      id: 1,
-      userId: 283,
-      userAvatar:
-        'https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKMezSxtOImrC9lbhwHiazYwck3xwrEcO7VJfG6WQo260whaeVNoByE5RreiaGsGfOMlIiaDhSaA991w/132',
-      userNickname: '辉辉鸭' + i,
-      lastMessageTime: getNowDateTime(),
-      lastMessageContent:
-        '[爱心][爱心]你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇',
-      lastMessageContentType: 1,
-      adminPinned: false,
-      userDeleted: false,
-      adminDeleted: false,
-      adminUnreadMessageCount: 19
-    })
-  }
 }
 defineExpose({ getConversationList })
 const emits = defineEmits<{

+ 1 - 2
src/views/mall/promotion/kefu/components/message/ImageMessageItem.vue

@@ -9,12 +9,11 @@
             ? `mr-10px`
             : ''
       ]"
-      class="flex messages-center"
     >
       <el-image
         :src="message.content"
         fit="contain"
-        style="width: 200px; height: 200px"
+        style="width: 200px"
         @click="imagePreview(message.content)"
       />
     </div>

+ 2 - 3
src/views/mall/promotion/kefu/components/tools/PictureSelectUpload.vue

@@ -16,9 +16,8 @@ const emits = defineEmits<{
 // 选择并上传文件
 const selectAndUpload = async () => {
   const files: any = await getFiles()
-  message.success('图片发送请稍等。。。')
+  message.success('图片发送请稍等。。。')
   const res = await FileApi.updateFile({ file: files[0].file })
-  message.success('图片发送成功!')
   emits('send-picture', res.data)
 }
 
@@ -34,7 +33,7 @@ const selectAndUpload = async () => {
 async function getFiles(options = {}) {
   const { multiple, accept, limit, fileSize } = {
     multiple: true,
-    accept: 'image/jpeg, image/png, image/gif',
+    accept: 'image/jpeg, image/png, image/gif', // 默认选择图片
     limit: 1,
     fileSize: 500,
     ...options