From d0bd7d4cd7c216b8ca6eb71aebd205dc8ee84709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E7=BA=A7=E8=80=81=E7=99=BD=E5=85=94?= Date: Thu, 21 Aug 2025 17:44:47 +0800 Subject: [PATCH] =?UTF-8?q?feat(websocket):=20=E9=87=8D=E6=9E=84WebSocket?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E9=80=BB=E8=BE=91=E5=B9=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构WebSocket连接逻辑,使用新的URL参数构建方式 - 添加初始化连接时的CmdSignIn和CmdRequestWechatAccountsAliveStatus命令 - 修改WebSocket消息类型定义,简化消息结构 - 从CkChatStore获取accountId用于连接参数 - 移除Login页面中与WebSocket相关的冗余代码 --- Cunkebao/src/pages/login/Login.tsx | 48 +-------- Cunkebao/src/pages/pc/ckbox/api.ts | 25 ++++- .../pc/ckbox/components/SidebarMenu/index.tsx | 97 ++++++++++--------- Cunkebao/src/pages/pc/ckbox/index.tsx | 18 ++-- Cunkebao/src/pages/pc/ckbox/main.ts | 62 +++++++++++- Cunkebao/src/store/module/ckchat.ts | 2 +- Cunkebao/src/store/module/user.ts | 1 - Cunkebao/src/store/module/websocket.ts | 74 +++++++------- 8 files changed, 179 insertions(+), 148 deletions(-) diff --git a/Cunkebao/src/pages/login/Login.tsx b/Cunkebao/src/pages/login/Login.tsx index 197c410d..7cf8832c 100644 --- a/Cunkebao/src/pages/login/Login.tsx +++ b/Cunkebao/src/pages/login/Login.tsx @@ -8,14 +8,8 @@ import { } from "antd-mobile-icons"; import { useUserStore } from "@/store/module/user"; import { useCkChatStore } from "@/store/module/ckchat"; -import { useWebSocketStore } from "@/store/module/websocket"; -import { - loginWithPassword, - loginWithCode, - sendVerificationCode, - loginWithToken, - getChuKeBaoUserInfo, -} from "./api"; + +import { loginWithPassword, loginWithCode, sendVerificationCode } from "./api"; import style from "./login.module.scss"; const Login: React.FC = () => { @@ -26,8 +20,7 @@ const Login: React.FC = () => { const [showPassword, setShowPassword] = useState(false); const [agreeToTerms, setAgreeToTerms] = useState(false); - const { login, login2 } = useUserStore(); - const { setUserInfo, getAccountId } = useCkChatStore(); + const { login } = useUserStore(); // 倒计时效果 useEffect(() => { @@ -97,24 +90,6 @@ const Login: React.FC = () => { }); }; - const getToken2 = () => { - return new Promise((resolve, reject) => { - const params = { - grant_type: "password", - password: "kr123456", - username: "kr_xf3", - }; - loginWithToken(params) - .then(res => { - login2(res.access_token); - resolve(res.access_token); - }) - .catch(err => { - reject(err); - }); - }); - }; - // 登录处理 const handleLogin = async (values: any) => { if (!agreeToTerms) { @@ -127,23 +102,6 @@ const Login: React.FC = () => { .finally(() => { setLoading(false); }); - - //获取触客宝 - getToken2().then((Token: string) => { - getChuKeBaoUserInfo().then(res => { - setUserInfo(res); - // 使用WebSocket store连接 - const { connect } = useWebSocketStore.getState(); - connect({ - accessToken: Token, - accountId: getAccountId()?.toString() || "", - client: "kefu-client", - autoReconnect: true, - reconnectInterval: 3000, - maxReconnectAttempts: 5, - }); - }); - }); }; // 第三方登录处理 diff --git a/Cunkebao/src/pages/pc/ckbox/api.ts b/Cunkebao/src/pages/pc/ckbox/api.ts index ef1da61a..c79fe353 100644 --- a/Cunkebao/src/pages/pc/ckbox/api.ts +++ b/Cunkebao/src/pages/pc/ckbox/api.ts @@ -14,16 +14,31 @@ import { ChatSettings, } from "./data"; +//触客宝登陆 +export function loginWithToken(params: any) { + return request( + "/token", + params, + "POST", + { + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + }, + 1000, + ); +} + +// 获取触客宝用户信息 +export function getChuKeBaoUserInfo() { + return request("/api/account/self", {}, "GET"); +} + // 获取联系人列表 export const getContactList = (params: { prevId: number; count: number }) => { return request("/api/wechatFriend/list", params, "GET"); }; -// 获取聊天会话列表 -export const getChatSessions = (): Promise => { - return request("/v1/chats/sessions", {}, "GET"); -}; - // 搜索联系人 export const getChatMessage = (params: { wechatAccountId: number; diff --git a/Cunkebao/src/pages/pc/ckbox/components/SidebarMenu/index.tsx b/Cunkebao/src/pages/pc/ckbox/components/SidebarMenu/index.tsx index 85b99318..e4da3996 100644 --- a/Cunkebao/src/pages/pc/ckbox/components/SidebarMenu/index.tsx +++ b/Cunkebao/src/pages/pc/ckbox/components/SidebarMenu/index.tsx @@ -12,7 +12,6 @@ import MessageList from "../MessageList/index"; import styles from "./SidebarMenu.module.scss"; const { Sider } = Layout; -const { TabPane } = Tabs; interface SidebarMenuProps { contacts: ContactData[]; @@ -72,52 +71,56 @@ const SidebarMenu: React.FC = ({ activeKey={activeTab} onChange={setActiveTab} className={styles.tabs} - > - - - 聊天 - - } - key="chats" - > - - - - - 联系人 - - } - key="contacts" - > - - - - - 群组 - - } - key="groups" - > -
- -

暂无群组

-
-
- + items={[ + { + key: "chats", + label: ( + + + 聊天 + + ), + children: ( + + ), + }, + { + key: "contacts", + label: ( + + + 联系人 + + ), + children: ( + + ), + }, + { + key: "groups", + label: ( + + + 群组 + + ), + children: ( +
+ +

暂无群组

+
+ ), + }, + ]} + /> ); }; diff --git a/Cunkebao/src/pages/pc/ckbox/index.tsx b/Cunkebao/src/pages/pc/ckbox/index.tsx index a70737e2..58533e02 100644 --- a/Cunkebao/src/pages/pc/ckbox/index.tsx +++ b/Cunkebao/src/pages/pc/ckbox/index.tsx @@ -12,9 +12,12 @@ const { Content } = Layout; import { loginWithToken, getChuKeBaoUserInfo } from "@/pages/login/api"; import { useCkChatStore } from "@/store/module/ckchat"; import { useUserStore } from "@/store/module/user"; +import { useWebSocketStore } from "@/store/module/websocket"; +import { chatInitAPIdata, getChatInfo } from "./main"; + const CkboxPage: React.FC = () => { const [messageApi, contextHolder] = message.useMessage(); - const [contacts, setContacts] = useState([]); + const [contacts, setContacts] = useState([]); const [chatSessions, setChatSessions] = useState([]); const [currentChat, setCurrentChat] = useState(null); const [loading, setLoading] = useState(false); @@ -23,16 +26,8 @@ const CkboxPage: React.FC = () => { const { login2 } = useUserStore(); useEffect(() => { - //获取触客宝 - getToken2().then(() => { - getChuKeBaoUserInfo().then(res => { - setUserInfo(res); - setTimeout(() => { - fetchContacts(); - fetchChatSessions(); - }); - }); - }); + const contactList = chatInitAPIdata(); + console.log(contactList); }, []); const getToken2 = () => { @@ -217,6 +212,7 @@ const CkboxPage: React.FC = () => { return ( + {/* */} {contextHolder} {/* 左侧边栏 */} { - console.log(connect); +const { setUserInfo, getAccountId } = useCkChatStore.getState(); +//获取触客宝基础信息 +export const chatInitAPIdata = async () => { + //获取Token + const Token = await getToken(); + //获取用户信息 + const userInfo = await getChuKeBaoUserInfo(); + setUserInfo(userInfo); + + //获取用户账号Id + const accountId = getAccountId(); + + //发起链接 + connect({ + accessToken: String(Token), + accountId: accountId, + client: "kefu-client", + cmdType: "CmdSignIn", + seq: 1, + }); + //获取联系人列表 + const contactList = await getContactList({ + prevId: userInfo.tenant.tenantType, + count: 100, + }); + + return contactList; +}; + +export const getChatInfo = () => { + //获取UserId + sendCommand("CmdRequestWechatAccountsAliveStatus", { + wechatAccountIds: ["300745", "4880930", "32686452"], + seq: 2, + }); + console.log("发送链接信息"); +}; +//获取token +const getToken = () => { + return new Promise((resolve, reject) => { + const params = { + grant_type: "password", + password: "kr123456", + username: "kr_xf3", + }; + loginWithToken(params) + .then(res => { + login2(res.access_token); + resolve(res.access_token); + }) + .catch(err => { + reject(err); + }); + }); }; diff --git a/Cunkebao/src/store/module/ckchat.ts b/Cunkebao/src/store/module/ckchat.ts index 7d4a9337..fccaf1ec 100644 --- a/Cunkebao/src/store/module/ckchat.ts +++ b/Cunkebao/src/store/module/ckchat.ts @@ -44,7 +44,7 @@ export const useCkChatStore = createPersistStore( // 获取账户ID getAccountId: () => { const state = useCkChatStore.getState(); - return state.userInfo?.account?.id || null; + return Number(state.userInfo?.account?.id) || null; }, // 获取租户ID diff --git a/Cunkebao/src/store/module/user.ts b/Cunkebao/src/store/module/user.ts index 070978c1..cf9b897e 100644 --- a/Cunkebao/src/store/module/user.ts +++ b/Cunkebao/src/store/module/user.ts @@ -80,7 +80,6 @@ export const useUserStore = createPersistStore( }, login2: token2 => { localStorage.setItem("token2", token2); - console.log(token2); set({ token2, isLoggedIn: true }); }, diff --git a/Cunkebao/src/store/module/websocket.ts b/Cunkebao/src/store/module/websocket.ts index 910fc7a7..a000f1a3 100644 --- a/Cunkebao/src/store/module/websocket.ts +++ b/Cunkebao/src/store/module/websocket.ts @@ -1,15 +1,15 @@ import { createPersistStore } from "@/store/createPersistStore"; import { Toast } from "antd-mobile"; import { useUserStore } from "./user"; +import { useCkChatStore } from "@/store/module/ckchat"; +const { getAccountId } = useCkChatStore.getState(); // WebSocket消息类型 export interface WebSocketMessage { - id: string; - type: string; - content: any; - timestamp: number; - sender?: string; - receiver?: string; + cmdType?: string; + seq?: number; + wechatAccountIds?: string[]; + [key: string]: any; } // WebSocket连接状态 @@ -25,9 +25,11 @@ export enum WebSocketStatus { interface WebSocketConfig { url: string; client: string; - accountId: string; + accountId: number; accessToken: string; autoReconnect: boolean; + cmdType: string; + seq: number; reconnectInterval: number; maxReconnectAttempts: number; } @@ -68,11 +70,13 @@ interface WebSocketState { // 默认配置 const DEFAULT_CONFIG: WebSocketConfig = { - url: (import.meta as any).env?.VITE_API_WS_URL || "ws://localhost:8080", + url: (import.meta as any).env?.VITE_API_WS_URL, client: "kefu-client", - accountId: "", + accountId: 0, accessToken: "", autoReconnect: true, + cmdType: "", // 添加默认的命令类型 + seq: 0, // 添加默认的序列号 reconnectInterval: 3000, maxReconnectAttempts: 5, }; @@ -103,24 +107,24 @@ export const useWebSocketStore = createPersistStore( }; // 获取用户信息 - const { token, token2, user } = useUserStore.getState(); - const accessToken = fullConfig.accessToken || token2 || token; + const { token2 } = useUserStore.getState(); - if (!accessToken) { + if (!token2) { Toast.show({ content: "未找到有效的访问令牌", position: "top" }); return; } - // 构建WebSocket URL - const params = { - client: fullConfig.client, - accountId: fullConfig.accountId || user?.s2_accountId || "", - accessToken: accessToken, - t: Date.now().toString(), - }; + console.log("获取connect参数", getAccountId()); - const wsUrl = - fullConfig.url + "?" + new URLSearchParams(params).toString(); + // 构建WebSocket URL + const params = new URLSearchParams({ + client: fullConfig.client.toString(), + accountId: getAccountId().toString(), + accessToken: token2, + t: Date.now().toString(), + }); + + const wsUrl = fullConfig.url + "?" + params; set({ status: WebSocketStatus.CONNECTING, @@ -166,7 +170,7 @@ export const useWebSocketStore = createPersistStore( }, // 发送消息 - sendMessage: (message: Omit) => { + sendMessage: message => { const currentState = get(); if ( @@ -179,8 +183,6 @@ export const useWebSocketStore = createPersistStore( const fullMessage: WebSocketMessage = { ...message, - id: Date.now().toString(), - timestamp: Date.now(), }; try { @@ -204,16 +206,8 @@ export const useWebSocketStore = createPersistStore( return; } - const { user } = useUserStore.getState(); - const { token, token2 } = useUserStore.getState(); - const accessToken = token2 || token; - const command = { - accessToken: accessToken, - accountId: user?.s2_accountId, - client: currentState.config?.client || "kefu-client", - cmdType: cmdType, - seq: Date.now(), + cmdType, ...data, }; @@ -255,10 +249,20 @@ export const useWebSocketStore = createPersistStore( }); console.log("WebSocket连接成功"); - + const { token2 } = useUserStore.getState(); // 发送登录命令 if (currentState.config) { - currentState.sendCommand("CmdSignIn"); + currentState.sendCommand("CmdSignIn", { + accessToken: token2, + accountId: Number(getAccountId()), + client: currentState.config?.client || "kefu-client", + seq: currentState.config?.seq || 1, + }); + //获取UserId + currentState.sendCommand("CmdRequestWechatAccountsAliveStatus", { + wechatAccountIds: ["300745", "4880930", "32686452"], + seq: 2, + }); } Toast.show({ content: "WebSocket连接成功", position: "top" });