sunshibo hai 23 horas
pai
achega
22e8cad0b6
Modificáronse 1 ficheiros con 61 adicións e 28 borrados
  1. 61 28
      src/views/storeDecoration/decorationChat.vue

+ 61 - 28
src/views/storeDecoration/decorationChat.vue

@@ -16,9 +16,25 @@
       </div>
       <div v-else class="message-list">
         <div v-for="(msg, index) in messages" :key="msg.id || index" :class="['message-item', isMine(msg) ? 'mine' : 'other']">
-          <el-avatar class="msg-avatar" :src="isMine(msg) ? myAvatar : ownerAvatar" :size="40">
-            <!-- <span class="avatar-fallback">{{ (isMine(msg) ? myName : ownerName).slice(0, 1) }}</span> -->
-          </el-avatar>
+          <!-- 与 dynamicManagement/myDynamic 一致:有图用 headImg 链,无图用灰底 + Avatar 图标(勿用 localhost 假地址) -->
+          <div class="msg-avatar">
+            <template v-if="isMine(msg)">
+              <img v-if="myAvatarUrl" :src="myAvatarUrl" class="msg-avatar-img" alt="" />
+              <div v-else class="msg-avatar-fallback" aria-hidden="true">
+                <el-icon :size="22">
+                  <Avatar />
+                </el-icon>
+              </div>
+            </template>
+            <template v-else>
+              <img v-if="ownerAvatarDisplay" :src="ownerAvatarDisplay" class="msg-avatar-img" alt="" />
+              <div v-else class="msg-avatar-fallback" aria-hidden="true">
+                <el-icon :size="22">
+                  <Avatar />
+                </el-icon>
+              </div>
+            </template>
+          </div>
           <div class="msg-body">
             <div class="msg-time">
               {{ msg.createdTime }}
@@ -96,7 +112,7 @@
 import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch } from "vue";
 import { useRoute, useRouter } from "vue-router";
 import { ElMessage } from "element-plus";
-import { ArrowLeft, Loading, Picture, VideoPlay } from "@element-plus/icons-vue";
+import { ArrowLeft, Avatar, Loading, Picture, VideoPlay } from "@element-plus/icons-vue";
 import { useWebSocketStore } from "@/stores/modules/websocket";
 import { getChatRecord, messageRead, socketStatus, uploadChatFile } from "@/api/modules/storeDecoration";
 import { localGet } from "@/utils";
@@ -128,14 +144,23 @@ let statusTimer: ReturnType<typeof setInterval> | null = null;
 
 const userInfo = computed(() => localGet("geeker-user")?.userInfo || {});
 
-// 自己头像与名称(用于气泡旁头像)
-const myAvatar = computed(
-  () =>
-    userInfo.value?.headImg ||
-    userInfo.value?.avatar ||
-    userInfo.value?.userImage ||
-    "http://localhost:5173/static/activity/avatar.svg"
-);
+/** 与 myDynamic.vue「cachedHeadImg」一致:geeker-user 的 headImg → avatar;无有效地址则空串走图标占位 */
+function pickUserHeadUrl(u: Record<string, any> | undefined): string {
+  if (!u) return "";
+  const raw = u.headImg || u.avatar || u.userImage || "";
+  const s = String(raw).trim();
+  return s;
+}
+
+const myAvatarUrl = computed(() => pickUserHeadUrl(userInfo.value as Record<string, any>));
+
+const ownerAvatarDisplay = computed(() => {
+  const s = String(ownerAvatar.value ?? "").trim();
+  if (!s) return "";
+  // 历史占位:无效本地路径,与 myDynamic 无头像态一致改用语义占位
+  if (s.includes("localhost:5173/static/activity/avatar.svg")) return "";
+  return s;
+});
 
 const isMine = (msg: any) => String(msg.senderId || "") === String(sendId.value);
 
@@ -435,9 +460,7 @@ watch(
     if (q?.receiverId) {
       receiverId.value = String(q.receiverId);
       ownerName.value = decodeURIComponent(String(q.uName || q.ownerName || "业主"));
-      ownerAvatar.value = q.userImage
-        ? decodeURIComponent(String(q.userImage))
-        : "http://localhost:5173/static/activity/avatar.svg";
+      ownerAvatar.value = q.userImage ? decodeURIComponent(String(q.userImage)) : "";
       requirementId.value = String(q.id || q.requirementId || "");
       loadChatRecord();
     }
@@ -448,9 +471,7 @@ watch(
 onMounted(async () => {
   receiverId.value = String(route.query.receiverId || "");
   ownerName.value = decodeURIComponent(String(route.query.uName || route.query.ownerName || "业主"));
-  ownerAvatar.value = route.query.userImage
-    ? decodeURIComponent(String(route.query.userImage))
-    : "http://localhost:5173/static/activity/avatar.svg";
+  ownerAvatar.value = route.query.userImage ? decodeURIComponent(String(route.query.userImage)) : "";
   requirementId.value = String(route.query.id || route.query.requirementId || "");
 
   if (!receiverId.value) {
@@ -520,17 +541,29 @@ onBeforeUnmount(() => {
     align-items: flex-start;
     .msg-avatar {
       flex-shrink: 0;
+      width: 40px;
+      height: 40px;
       overflow: hidden;
-      .avatar-fallback {
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        width: 100%;
-        height: 100%;
-        font-size: 16px;
-        color: #ffffff;
-        background: #c0c4cc;
-      }
+      border-radius: 50%;
+    }
+    .msg-avatar-img {
+      display: block;
+      width: 40px;
+      height: 40px;
+      object-fit: cover;
+      border-radius: 50%;
+    }
+
+    /* 与 myDynamic .user-avatar-large 无图态一致:浅灰圆底 + User 轮廓图标 */
+    .msg-avatar-fallback {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: 40px;
+      height: 40px;
+      color: #909399;
+      background: #f5f7fa;
+      border-radius: 50%;
     }
     &.mine {
       flex-direction: row-reverse;