Kaynağa Gözat

上传优化

wkw 1 ay önce
ebeveyn
işleme
72b179ef6d
2 değiştirilmiş dosya ile 61 ekleme ve 18 silme
  1. 39 13
      src/views/im/chat/index.vue
  2. 22 5
      src/views/im/publish/index.vue

+ 39 - 13
src/views/im/chat/index.vue

@@ -136,9 +136,14 @@
       </div>
 
       <!-- 录音状态浮层 -->
-      <div v-if="recording" class="recording-toast">
+      <!-- <div v-if="recording" class="recording-toast">
         <div v-if="cancelRecording" class="cancel-msg">松开手指,取消发送</div>
         <div v-else class="send-msg">松开发送,上滑取消</div>
+      </div> -->
+      <div v-if="recording" class="recording-toast">
+        <div class="mic-icon"></div>
+        <div v-if="cancelRecording" class="cancel-msg">松开手指,取消发送</div>
+        <div v-else class="send-msg">手指上滑,取消发送</div>
       </div>
 
       <!-- 表情面板 -->
@@ -885,6 +890,7 @@ const goDetail = () =>{
   background: black;
   object-fit: cover;
 }
+/* 按住说话按钮 */
 .hold-talk-btn {
   flex: 1;
   text-align: center;
@@ -901,21 +907,41 @@ const goDetail = () =>{
   line-height: 24px;
   border: 1px solid #f5f5f5;
 }
+
+/* 录音中的浮层提示 */
 .recording-toast {
   position: fixed;
-  bottom: 120px;
+  bottom: 80px;
   left: 50%;
   transform: translateX(-50%);
-  padding: 12px 20px;
-  background: rgba(0, 0, 0, 0.75);
-  color: #fff;
-  border-radius: 8px;
-  font-size: 14px;
-  user-select: none;
-  -webkit-user-select: none;
-  -webkit-touch-callout: none;
-}
-.cancel-msg {
-  color: #ff4d4f;
+  width: 160px;
+  min-height: 160px;
+  background: rgba(0, 0, 0, 0.85);
+  border-radius: 12px;
+  padding: 16px;
+  box-sizing: border-box;
+  text-align: center;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+
+  .mic-icon {
+    width: 60px;
+    height: 60px;
+    background: url("https://img.icons8.com/ios-filled/100/ffffff/microphone.png") no-repeat center center;
+    background-size: contain;
+    margin-bottom: 16px;
+  }
+
+  .send-msg {
+    color: #fff;
+    font-size: 14px;
+  }
+
+  .cancel-msg {
+    color: #ff4d4f;
+    font-size: 14px;
+  }
 }
 </style>

+ 22 - 5
src/views/im/publish/index.vue

@@ -43,33 +43,48 @@ const router = useRouter();
 const message = ref("");
 const fileList = ref([]);
 const loading = ref(false);
+const uploading = ref(false); // 标记是否正在上传
 
-// 按钮禁用:没有文字 && 没有文件 时禁用
+// 按钮禁用:没有文字 && 没有文件 时禁用;或者正在上传时禁用
 const isDisabled = computed(() => {
-  return !(message.value.trim() || fileList.value.length > 0);
+  return uploading.value || !(message.value.trim() || fileList.value.length > 0);
 });
 
-// 选中文件后的处理逻辑(支持多选上传)
+// 选中文件后的处理逻辑(支持多选上传)——逐个上传
 const afterRead = async (file) => {
-  const files = Array.isArray(file) ? file : [file]; // 兼容单选和多选
+  const files = Array.isArray(file) ? file : [file];
+  uploading.value = true;
+
   for (const f of files) {
     const rawFile = f.file;
     const formData = new FormData();
     formData.append("image", rawFile);
 
+    // 先标记状态
+    f.status = "uploading";
+
     try {
       const res = await hostUploadImg(formData);
       f.url = res.data.all_url;
+      f.status = "done";
     } catch (err) {
       console.error("上传失败:", err);
       f.status = "failed";
       f.message = "上传失败";
     }
   }
+
+  uploading.value = false;
 };
 
 // 发布按钮逻辑
 const confirm = async () => {
+  // 检查是否有图片没上传完
+  if (fileList.value.some((item) => item.status === "uploading")) {
+    showToast("请等待图片上传完成");
+    return;
+  }
+
   let params = {
     content: message.value,
     type: "0", // 图片
@@ -77,7 +92,9 @@ const confirm = async () => {
   };
 
   if (fileList.value.length > 0) {
-    params.images = fileList.value.map((item) => item.url);
+    params.images = fileList.value
+      .filter((item) => item.status === "done") // 只取成功的
+      .map((item) => item.url);
   }
 
   loading.value = true;