Jelajahi Sumber

增加分享功能 连接websorkt

lxr 2 bulan lalu
induk
melakukan
f93a120b80

+ 5 - 1
.env.development

@@ -24,7 +24,11 @@ VITE_API_URL_PLATFORM = /api/alienStorePlatform
 
 # 开发环境跨域代理,支持配置多个
 # VITE_PROXY = [["/api","https://api.ailien.shop"]] #生产环境
-# VITE_PROXY = [["/api","http://192.168.2.57:7000"]] # 邹建宇
+VITE_PROXY = [["/api","http://120.26.186.130:8000"]] # 邹建宇
+
+# WebSocket 基础地址(分享等能力,与商家端一致)
+VITE_WS_BASE = ws://120.26.186.130:8000/alienStore/socket/
+
 
 # 接口加密配置
 # 加密功能总开关

+ 100 - 0
src/stores/modules/websocket.ts

@@ -0,0 +1,100 @@
+import { defineStore } from "pinia";
+import { ref } from "vue";
+
+/**
+ * WebSocket Store(浏览器端)
+ * 与商家端 @/store/websocket 消息格式一致,用于分享动态等
+ */
+export const useWebSocketStore = defineStore("websocket", () => {
+  const socket = ref<WebSocket | null>(null);
+  const isConnected = ref(false);
+  const isConnecting = ref(false);
+  const lastConnectedUrl = ref("");
+
+  const connect = (url: string): Promise<boolean> => {
+    if (isConnected.value && lastConnectedUrl.value === url) {
+      return Promise.resolve(true);
+    }
+    if (socket.value) {
+      try {
+        socket.value.close();
+      } catch (e) {
+        console.warn("关闭旧连接失败:", e);
+      }
+      socket.value = null;
+      isConnected.value = false;
+    }
+
+    isConnecting.value = true;
+    lastConnectedUrl.value = url;
+
+    return new Promise(resolve => {
+      try {
+        const ws = new WebSocket(url);
+        socket.value = ws;
+
+        ws.onopen = () => {
+          isConnected.value = true;
+          isConnecting.value = false;
+          resolve(true);
+        };
+
+        ws.onclose = () => {
+          isConnected.value = false;
+          isConnecting.value = false;
+          socket.value = null;
+        };
+
+        ws.onerror = () => {
+          isConnected.value = false;
+          isConnecting.value = false;
+          resolve(false);
+        };
+      } catch (e) {
+        console.error("WebSocket 连接异常:", e);
+        isConnecting.value = false;
+        resolve(false);
+      }
+    });
+  };
+
+  const sendMessage = (data: Record<string, unknown>): Promise<boolean> => {
+    return new Promise(resolve => {
+      if (!isConnected.value || !socket.value || socket.value.readyState !== WebSocket.OPEN) {
+        console.warn("WebSocket 未连接,无法发送消息");
+        resolve(false);
+        return;
+      }
+      try {
+        const message = JSON.stringify(data);
+        socket.value.send(message);
+        resolve(true);
+      } catch (e) {
+        console.error("消息发送异常:", e);
+        resolve(false);
+      }
+    });
+  };
+
+  const disconnect = () => {
+    if (socket.value) {
+      try {
+        socket.value.close();
+      } catch (_) {}
+      socket.value = null;
+    }
+    isConnected.value = false;
+    isConnecting.value = false;
+    lastConnectedUrl.value = "";
+  };
+
+  return {
+    socket,
+    isConnected,
+    isConnecting,
+    lastConnectedUrl,
+    connect,
+    sendMessage,
+    disconnect
+  };
+});

+ 1 - 0
src/typings/global.d.ts

@@ -61,6 +61,7 @@ declare interface ViteEnv {
   VITE_API_ENCRYPTION_ENABLED: string;
   VITE_CRYPTO_KEY: string;
   VITE_CRYPTO_IV: string;
+  VITE_WS_BASE?: string;
 }
 
 interface ImportMetaEnv extends ViteEnv {

+ 52 - 6
src/views/dynamicManagement/index.vue

@@ -533,9 +533,14 @@ import {
 
 // import { uploadImg } from "@/api/modules/upload";
 import { useUserStore } from "@/stores/modules/user";
+import { useWebSocketStore } from "@/stores/modules/websocket";
 
 const router = useRouter();
 const userStore = useUserStore();
+const socketStore = useWebSocketStore();
+
+// WebSocket 基础地址(与商家端一致,分享前连接)
+const WS_BASE = import.meta.env.VITE_WS_BASE || "ws://192.168.10.80:8000/alienStore/socket/";
 
 // 举报原因到违规类型的映射
 const violationTypeMap: Record<string, number> = {
@@ -1142,8 +1147,24 @@ const handleCancelReply = () => {
   commentInput.value = "";
 };
 
-// 分享
+// 分享(参考商家端 newDetail:分享前先连接 WebSocket)
 const handleShare = async () => {
+  const phone = userStore.userInfo?.phone || "";
+  const senderId = phone.startsWith("store_") ? phone : `store_${phone}`;
+  const wsUrl = `${WS_BASE.replace(/\/$/, "")}/${senderId}`;
+  try {
+    if (!socketStore.isConnected || socketStore.lastConnectedUrl !== wsUrl) {
+      const connected = await socketStore.connect(wsUrl);
+      if (!connected) {
+        ElMessage.warning("连接失败,请稍后重试");
+        return;
+      }
+    }
+  } catch (e) {
+    console.error("WebSocket 连接失败:", e);
+    ElMessage.warning("连接失败,请稍后重试");
+    return;
+  }
   shareDialogVisible.value = true;
   await loadShareFriendList();
 };
@@ -1204,7 +1225,7 @@ const handleRemoveFriend = (friendId: number) => {
   }
 };
 
-// 确认分享
+// 确认分享(参考商家端 newDetail:通过 WebSocket sendMessage 发送给每位好友,再调 addTransferCount)
 const handleConfirmShare = async () => {
   if (selectedFriends.value.length === 0) {
     ElMessage.warning("请选择要分享的好友");
@@ -1216,10 +1237,34 @@ const handleConfirmShare = async () => {
     return;
   }
 
+  const phone = userStore.userInfo?.phone || "";
+  const senderId = phone.startsWith("store_") ? phone : `store_${phone}`;
+  const detailPayload = {
+    ...currentDetail.value,
+    imageList: currentDetail.value.imagePath.split(","),
+    cover: currentDetail.value.imagePath.split(",")[0]
+  };
   try {
     shareSubmitting.value = true;
 
-    // 调用 addTransferCount 接口,传递动态 id
+    // 先通过 WebSocket 给每位选中好友发送动态分享消息(与商家端 sendMessage 格式一致)
+    for (const friendId of selectedFriends.value) {
+      const friend = shareFriendList.value.find(f => f.id === friendId);
+      const receiverId = friend?.phoneId || friend?.id;
+      if (!receiverId) continue;
+      await socketStore.sendMessage({
+        category: "message",
+        receiverId,
+        senderId,
+        type: 3,
+        text: {
+          sendType: "dynamicShare",
+          url: JSON.stringify(detailPayload)
+        }
+      });
+    }
+
+    // 再调用 addTransferCount 接口,传递动态 id(与商家端一致)
     const res: any = await addTransferCount({
       id: currentDetail.value.id
     });
@@ -1227,9 +1272,10 @@ const handleConfirmShare = async () => {
     if (res.code === 200) {
       ElMessage.success(`已分享给 ${selectedFriends.value.length} 位好友`);
       shareDialogVisible.value = false;
-
-      // 可以在这里更新动态的分享数(如果需要的话)
-      console.log("分享成功,动态ID:", currentDetail.value.id);
+      // 更新当前详情的分享数
+      if (typeof (currentDetail.value as any).transferCount === "number") {
+        (currentDetail.value as any).transferCount += selectedFriends.value.length;
+      }
     } else {
       ElMessage.error(res.message || "分享失败");
     }