ソースを参照

feat:会话存档聊天记录展示

caoliqin 4 日 前
コミット
5e2c710606
1 ファイル変更93 行追加15 行削除
  1. 93 15
      src/views/qw/qwMsgAuditMessage/index.vue

+ 93 - 15
src/views/qw/qwMsgAuditMessage/index.vue

@@ -140,17 +140,39 @@
                   :class="{ 'is-self': isSelfMessage(msg) }"
                 >
                   <div class="msg-meta">
-                    <span class="from">{{ msg.fromUser }}</span>
+                    <span class="from">{{ msg.fromUserName }}</span>
                     <span class="time">{{ formatMsgTime(msg.msgTime) }}</span>
                     <span v-if="chatScope === 'group' && msg.roomId" class="room-tag">群 {{ shortRoom(msg.roomId) }}</span>
                   </div>
                   <div class="bubble">
                     <div v-if="msg.textContent" class="text">{{ msg.textContent }}</div>
-                    <div v-else-if="msg.mediaOssUrl" class="media">
-                      <a :href="msg.mediaOssUrl" target="_blank" rel="noopener">查看媒体</a>
-                      <span v-if="msg.mediaFileName" class="file-name">{{ msg.mediaFileName }}</span>
+                    <div
+                      v-if="msg.mediaOssUrl"
+                      class="media-box"
+                      :class="'media-kind-' + msgMediaCategory(msg)"
+                    >
+                      <template v-if="msgMediaCategory(msg) === 'image'">
+                        <img class="media-img" :src="msg.mediaOssUrl" alt="图片" />
+                      </template>
+                      <template v-else-if="msgMediaCategory(msg) === 'video'">
+                        <div class="media-type-tag">{{ mediaKindTitle(msg) }}</div>
+                        <video class="media-video" :src="msg.mediaOssUrl" controls preload="metadata" />
+                      </template>
+                      <template v-else-if="msgMediaCategory(msg) === 'voice'">
+                        <div class="media-type-tag">{{ mediaKindTitle(msg) }}</div>
+                        <audio class="media-audio" :src="msg.mediaOssUrl" controls preload="metadata" />
+                      </template>
+                      <template v-else>
+                        <a
+                          class="media-file-link"
+                          :href="msg.mediaOssUrl"
+                          target="_blank"
+                          rel="noopener"
+                        >{{ mediaKindTitle(msg) }}</a>
+                        <span v-if="msg.mediaFileName" class="media-file-name">{{ msg.mediaFileName }}</span>
+                      </template>
                     </div>
-                    <div v-else class="fallback text-muted">
+                    <div v-if="!msg.textContent && !msg.mediaOssUrl" class="fallback text-muted">
                       [{{ msgTypeLabel(msg.msgType) }}]
                       <template v-if="msg.mediaFileName">{{ msg.mediaFileName }}</template>
                     </div>
@@ -258,6 +280,20 @@ export default {
       if (type == null || type === '') return '未知类型'
       return String(type)
     },
+    // 仅按 msgType 字符串区分:image / emotion → 图片,voice → 语音,video → 视频,file → 文件,其余按文件
+    msgMediaCategory(msg) {
+      if (!msg) return 'file'
+      const s = msg.msgType == null ? '' : String(msg.msgType).toLowerCase()
+      if (s === 'image' || s === 'emotion') return 'image'
+      if (s === 'voice') return 'voice'
+      if (s === 'video') return 'video'
+      if (s === 'file') return 'file'
+      return 'file'
+    },
+    mediaKindTitle(msg) {
+      const map = { image: '图片', voice: '语音', video: '视频', file: '文件' }
+      return map[this.msgMediaCategory(msg)] || '附件'
+    },
     // 是否当前员工自己发的(用于绿气泡靠右)
     isSelfMessage(msg) {
       if (!this.selectedUser || !msg.fromUser) return false
@@ -455,6 +491,7 @@ export default {
         return
       }
       const res = await listQwMsgAuditMessage({
+        corpId: this.corpId,
         conversationKey: key,
         pageNum,
         pageSize: this.msgPageSize
@@ -827,12 +864,13 @@ export default {
   }
 
   .msg-list {
-    padding: 16px;
-    max-width: 880px;
-    margin: 0 auto;
+    width: 100%;
+    box-sizing: border-box;
+    padding: 12px 15px;
   }
 
   .msg-row {
+    width: 100%;
     margin-bottom: 14px;
     display: flex;
     flex-direction: column;
@@ -864,7 +902,8 @@ export default {
   }
 
   .bubble {
-    max-width: 75%;
+    // 用插值交给浏览器解析 min(),避免 dart-sass 把 min 当 Sass 函数报单位不兼容
+    max-width: #{"min(78%, 560px)"};
     padding: 8px 12px;
     border-radius: 6px;
     background: #fff;
@@ -876,14 +915,53 @@ export default {
       font-size: 14px;
     }
 
-    .media {
+    .text + .media-box {
+      margin-top: 8px;
+    }
+
+    .media-box {
       font-size: 13px;
+      max-width: 100%;
+    }
 
-      .file-name {
-        display: block;
-        margin-top: 4px;
-        color: #606266;
-      }
+    .media-type-tag {
+      font-size: 12px;
+      color: #909399;
+      margin-bottom: 6px;
+    }
+
+    .media-img {
+      display: block;
+      max-width: 220px;
+      max-height: 260px;
+      border-radius: 4px;
+    }
+
+    .media-video {
+      display: block;
+      max-width: 280px;
+      max-height: 220px;
+      border-radius: 4px;
+      background: #000;
+    }
+
+    .media-audio {
+      display: block;
+      width: 260px;
+      max-width: 100%;
+      height: 36px;
+    }
+
+    .media-file-link {
+      color: #409eff;
+    }
+
+    .media-file-name {
+      display: block;
+      margin-top: 4px;
+      color: #606266;
+      font-size: 12px;
+      word-break: break-all;
     }
   }