Procházet zdrojové kódy

update ChatDialogue.vue

reghao před 1 týdnem
rodič
revize
aac3395372
1 změnil soubory, kde provedl 132 přidání a 34 odebrání
  1. 132 34
      src/views/chat/ChatDialogue.vue

+ 132 - 34
src/views/chat/ChatDialogue.vue

@@ -16,7 +16,7 @@
 
       <div
         v-for="(msg, index) in formattedMessageList"
-        :key="msg.messageId"
+        :key="msg.messageId + index"
       >
         <div v-if="msg._showTimeText" class="chat-time-node">
           <span>{{ msg._showTimeText }}</span>
@@ -35,12 +35,12 @@
           <div class="message-content">
             <div v-if="msg.msgType === 1" class="msg-text">{{ msg.content }}</div>
 
-            <div v-else-if="msg.msgType === 2" class="msg-image" @click="onPreview(msg.objectUrl)">
+            <div v-else-if="msg.msgType === 22" class="msg-image" @click="onPreview(msg.objectUrl)">
               <el-image :src="msg.objectUrl" fit="cover" />
             </div>
 
             <div
-              v-else-if="msg.msgType === 3"
+              v-else-if="msg.msgType === 23"
               class="msg-audio"
               :style="{ width: 60 + (msg.duration || 5) * 4 + 'px' }"
               @click="toggleAudio(msg, msg.messageId)"
@@ -50,7 +50,7 @@
               <div v-if="msg.isUnread" class="audio-unread-dot" />
             </div>
 
-            <div v-else-if="msg.msgType === 4" class="msg-video" @click="viewVideo(msg.objectUrl)">
+            <div v-else-if="msg.msgType === 24" class="msg-video" @click="viewVideo(msg.objectUrl)">
               <el-image :src="require('@/assets/img/video.jpg')" fit="cover" class="video-cover" />
               <div class="video-play-mask">
                 <i class="el-icon-video-play play-icon" />
@@ -58,7 +58,7 @@
             </div>
 
             <div
-              v-else-if="[5, 6, 7, 99].includes(msg.msgType)"
+              v-else-if="[21, 25, 26, 27].includes(msg.msgType)"
               :class="['msg-file', { 'is-expired': msg.fileExpired }]"
               @click="msg.fileExpired ? handleExpiredClick() : handleFileClick(msg)"
             >
@@ -78,22 +78,27 @@
               </div>
             </div>
 
-            <div v-else-if="msg.msgType === 8" class="msg-record">
+            <div v-else-if="msg.msgType === 5" class="msg-record">
               <div class="record-title">聊天记录</div>
               <div v-for="(line, idx) in msg.previewLines" :key="idx" class="record-preview">
                 {{ line }}
               </div>
             </div>
 
-            <div v-else-if="msg.msgType === 9" class="msg-transfer" @click="handleTransferClick(msg)">
+            <div
+              v-else-if="msg.msgType === 2"
+              :class="['msg-transfer', { 'is-received': msg.transferStatus === 2 }]"
+              @click="handleTransferClick(msg)"
+            >
               <div class="transfer-main">
                 <div class="transfer-icon-box">
-                  <i class="el-icon-refresh" />
+                  <i :class="msg.transferStatus === 2 ? 'el-icon-check' : 'el-icon-refresh'" />
                 </div>
                 <div class="transfer-info">
                   <div class="transfer-amount">¥{{ msg.amount || '0.00' }}</div>
                   <div class="transfer-status">
-                    {{ msg.transferStatus === 1 ? '转账给对方' : '已被接收' }}
+                    <span v-if="msg.transferStatus === 1">待接收 / 点击收钱</span>
+                    <span v-else-if="msg.transferStatus === 2">已被接收</span>
                   </div>
                 </div>
               </div>
@@ -101,20 +106,33 @@
             </div>
 
             <div
-              v-else-if="msg.msgType === 10"
-              :class="['msg-lucky-money', { 'is-opened': msg.hbStatus === 1 }]"
+              v-else-if="msg.msgType === 3"
+              :class="['msg-lucky-money', { 'is-opened': msg.isSelfOpened }]"
               @click="handleLuckyMoneyClick(msg)"
             >
               <div class="hb-main">
                 <div class="hb-icon-box">
-                  <i :class="msg.hbStatus === 1 ? 'el-icon-folder-opened' : 'el-icon-wallet'" />
+                  <i :class="msg.isSelfOpened ? 'el-icon-folder-opened' : 'el-icon-wallet'" />
                 </div>
                 <div class="hb-info">
                   <div class="hb-title">{{ msg.content || '恭喜发财,大吉大利' }}</div>
-                  <div v-if="msg.hbStatus === 1" class="hb-status">红包已被领完</div>
+
+                  <div class="hb-status">
+                    <span v-if="msg.isSelfOpened">
+                      {{ msg.chatType === 2 ? '已抢到红包' : '红包已被接收' }}
+                    </span>
+                    <span v-else-if="msg.chatType === 2 && msg.transferStatus === 2">
+                      红包已被领完
+                    </span>
+                    <span v-else-if="msg.transferStatus === 3">
+                      红包已过期
+                    </span>
+                  </div>
                 </div>
               </div>
-              <div class="hb-footer">微信红包</div>
+              <div class="hb-footer">
+                {{ msg.chatType === 2 ? '微信群红包' : '微信红包' }}
+              </div>
             </div>
           </div>
         </div>
@@ -238,20 +256,72 @@ export default {
     this.parseRouteParams()
   },
   methods: {
+    /**
+     * 点击转账气泡
+     */
     handleTransferClick(msg) {
-      if (msg.transferStatus === 1) {
-        this.$message.success(`点击了转账,金额:${msg.amount} 元,确认收钱逻辑待对接`)
-        // 真实业务:调用后端确认收钱接口,然后把 msg.transferStatus 改为 2
-      } else {
-        this.$message.info('该转账已完成收钱')
+      // 如果已经收过钱了,直接返回或看详情
+      if (msg.transferStatus === 2) {
+        this.$message.info('该转账已完成,可在钱包明细中查看')
+        return
       }
+
+      // 触发高仿微信收钱动画
+      const loading = this.$loading({
+        lock: true,
+        text: '正在收钱...',
+        spinner: 'el-icon-loading', // 产生菊花转圈动效
+        background: 'rgba(0, 0, 0, 0.7)',
+        customClass: 'wechat-loading-mask' // 注入自定义样式,包装成微信黑框提示
+      })
+
+      // 模拟网络请求延迟(1.5秒后收钱成功)
+      setTimeout(() => {
+        loading.close() // 关闭收钱动画
+
+        // 弹出成功提示
+        this.$message({
+          message: `成功入账 ¥${msg.amount} 元!`,
+          type: 'success'
+        })
+
+        // 核心:改变状态。由于给外层加了 transition,气泡颜色会当场丝滑变淡
+        this.$set(msg, 'transferStatus', 2)
+
+        // 实际业务:此处应该向后端发请求更新数据库:
+        // receiveTransfer({ messageId: msg.messageId }).then(resp => { ... })
+      }, 1500)
     },
     handleLuckyMoneyClick(msg) {
-      if (msg.hbStatus !== 1) {
-        this.$message.success('啪!打开红包动画,恭喜发财!')
-        // 真实业务:弹出红包开启动画组件,调用抢红包接口,成功后将 msg.hbStatus 改为 1
+      // 1. 如果已经过期了
+      if (msg.transferStatus === 3) {
+        this.$message.info('该红包已超过24小时,已过期失效')
+        return
+      }
+
+      // 2. 如果是群聊红包 (chatType === 2)
+      if (msg.chatType === 2) {
+        if (msg.isSelfOpened) {
+          // 自己抢过了,点击直接看【群红包领取详情列表】(看手气最佳是谁)
+          this.$message.info('正在查看群红包领取详情...')
+        } else if (msg.transferStatus === 1) {
+          // 自己没抢过,但红包空了,点击弹窗提示“手慢了,红包派完了”,并把本地状态改为已读变灰
+          this.$message.warning('手慢了,红包已被领完!')
+          this.$set(msg, 'isSelfOpened', true)
+        } else {
+          // 核心:有福同享,啪!弹出微信大红圈“開”字动画
+          this.$message.success('弹出群红包【開】弹窗,开始拼手气!')
+          // 成功抢到后后端配合把 msg.isSelfOpened 改为 true
+        }
       } else {
-        this.$message.info('查看该红包的领取详情列表')
+        // 3. 如果是单聊点对点红包 (chatType === 1)
+        if (msg.isSelfOpened || msg.transferStatus === 1) {
+          this.$message.info('查看红包领取金额')
+        } else {
+          this.$message.success('成功拆开好友红包!')
+          this.$set(msg, 'isSelfOpened', true)
+          this.$set(msg, 'transferStatus', 2)
+        }
       }
     },
     /**
@@ -271,8 +341,8 @@ export default {
       }
 
       // 2. 根据文件后缀或 msgType 判断策略
-      // msgType 对应关系参考:5-Word, 6-Excel, 7-PDF, 99-ZIP
-      if (msg.msgType === 7 || url.toLowerCase().endsWith('.pdf')) {
+      // msgType 对应关系参考:25-Word, 26-Excel, 27-PDF, 99-ZIP
+      if (msg.msgType === 27 || url.toLowerCase().endsWith('.pdf')) {
         // ==== 策略 A:在线预览 (主要针对 PDF 或高版本浏览器支持的公有流) ====
         // window.open(url, '_blank')
       } else {
@@ -399,7 +469,7 @@ export default {
       getChatRecords(queryParams).then(resp => {
         if (resp.code === 0) {
           resp.data.list.forEach(msg => {
-            if ([5, 6, 7].includes(msg.msgType) && msg.content) {
+            if ([25, 26, 27].includes(msg.msgType) && msg.content) {
               // 假设后端 content 规则为 "文件名|大小|下载地址"
               const parts = msg.content.split('|')
               msg.fileName = parts[0] || '未知文件.docx'
@@ -431,8 +501,6 @@ export default {
                 payload.chatId = this.currentContact.chatId
                 payload.lastMessageId = this.lastReadMessageId
                 updateChatDialogue(payload).then(resp => {
-                  if (resp.code === 0) {
-                  }
                 })
               }
             } else {
@@ -504,8 +572,6 @@ export default {
               payload.chatId = this.currentContact.chatId
               payload.lastMessageId = this.lastReadMessageId
               updateChatDialogue(payload).then(resp => {
-                if (resp.code === 0) {
-                }
               })
             }
             break
@@ -617,10 +683,10 @@ export default {
     },
     getFileIcon(type) {
       const iconMap = {
-        5: 'el-icon-document text-word',
-        6: 'el-icon-s-order text-excel',
-        7: 'el-icon-document-checked text-pdf',
-        99: 'el-icon-box text-zip'
+        25: 'el-icon-document text-word',
+        26: 'el-icon-s-order text-excel',
+        27: 'el-icon-document-checked text-pdf',
+        28: 'el-icon-box text-zip'
       }
       return iconMap[type] || 'el-icon-document'
     },
@@ -1057,4 +1123,36 @@ export default {
 .msg-lucky-money.is-opened .hb-icon-box {
   color: rgba(255,255,255,0.6); /* 金色变白透明 */
 }
+
+/* 转账基础气泡(待接收) */
+.msg-transfer {
+  width: 230px;
+  background-color: #fa9d3b;
+  border-radius: 4px;
+  overflow: hidden;
+  cursor: pointer;
+  box-shadow: 0 1px 2px rgba(0,0,0,0.05);
+
+  /* 【新增核心动画线】:让所有属性变化时都走0.3秒的丝滑渐变 */
+  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
+}
+
+/* 【已接收状态】的灰色/淡橙色过渡样式 */
+.msg-transfer.is-received {
+  background-color: #fcdbb3; /* 模拟微信收钱后,卡片颜色变浅半透明 */
+}
+
+/* 微信特色:收钱后左侧圆圈背景和里面的对勾也会跟着变淡 */
+.msg-transfer.is-received .transfer-icon-box {
+  background: rgba(255, 255, 255, 0.4);
+  transform: rotate(0deg); /* 恢复正向显示对勾 */
+}
+
+/* 图标本身的旋转过渡动画 */
+.transfer-icon-box i {
+  transition: transform 0.3s ease;
+}
+.msg-transfer:not(.is-received) .transfer-icon-box i {
+  transform: rotate(45deg); /* 待收钱时箭头倾斜 */
+}
 </style>