feat(websocket): 重构WebSocket连接逻辑并添加初始化命令
- 重构WebSocket连接逻辑,使用新的URL参数构建方式 - 添加初始化连接时的CmdSignIn和CmdRequestWechatAccountsAliveStatus命令 - 修改WebSocket消息类型定义,简化消息结构 - 从CkChatStore获取accountId用于连接参数 - 移除Login页面中与WebSocket相关的冗余代码
This commit is contained in:
@@ -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,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 第三方登录处理
|
||||
|
||||
@@ -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<ChatSession[]> => {
|
||||
return request("/v1/chats/sessions", {}, "GET");
|
||||
};
|
||||
|
||||
// 搜索联系人
|
||||
export const getChatMessage = (params: {
|
||||
wechatAccountId: number;
|
||||
|
||||
@@ -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<SidebarMenuProps> = ({
|
||||
activeKey={activeTab}
|
||||
onChange={setActiveTab}
|
||||
className={styles.tabs}
|
||||
>
|
||||
<TabPane
|
||||
tab={
|
||||
<span>
|
||||
<MessageOutlined />
|
||||
聊天
|
||||
</span>
|
||||
}
|
||||
key="chats"
|
||||
>
|
||||
<MessageList
|
||||
sessions={getFilteredSessions()}
|
||||
currentChat={currentChat}
|
||||
onChatSelect={onChatSelect}
|
||||
/>
|
||||
</TabPane>
|
||||
<TabPane
|
||||
tab={
|
||||
<span>
|
||||
<UserOutlined />
|
||||
联系人
|
||||
</span>
|
||||
}
|
||||
key="contacts"
|
||||
>
|
||||
<ContactListSimple
|
||||
contacts={getFilteredContacts()}
|
||||
onContactClick={onContactClick}
|
||||
selectedContactId={currentChat?.id.split("_")[1]}
|
||||
/>
|
||||
</TabPane>
|
||||
<TabPane
|
||||
tab={
|
||||
<span>
|
||||
<TeamOutlined />
|
||||
群组
|
||||
</span>
|
||||
}
|
||||
key="groups"
|
||||
>
|
||||
<div className={styles.emptyState}>
|
||||
<TeamOutlined style={{ fontSize: 48, color: "#ccc" }} />
|
||||
<p>暂无群组</p>
|
||||
</div>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
items={[
|
||||
{
|
||||
key: "chats",
|
||||
label: (
|
||||
<span>
|
||||
<MessageOutlined />
|
||||
聊天
|
||||
</span>
|
||||
),
|
||||
children: (
|
||||
<MessageList
|
||||
sessions={getFilteredSessions()}
|
||||
currentChat={currentChat}
|
||||
onChatSelect={onChatSelect}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "contacts",
|
||||
label: (
|
||||
<span>
|
||||
<UserOutlined />
|
||||
联系人
|
||||
</span>
|
||||
),
|
||||
children: (
|
||||
<ContactListSimple
|
||||
contacts={getFilteredContacts()}
|
||||
onContactClick={onContactClick}
|
||||
selectedContactId={currentChat?.id.split("_")[1]}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "groups",
|
||||
label: (
|
||||
<span>
|
||||
<TeamOutlined />
|
||||
群组
|
||||
</span>
|
||||
),
|
||||
children: (
|
||||
<div className={styles.emptyState}>
|
||||
<TeamOutlined style={{ fontSize: 48, color: "#ccc" }} />
|
||||
<p>暂无群组</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Sider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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<ContactData[]>([]);
|
||||
const [contacts, setContacts] = useState<any[]>([]);
|
||||
const [chatSessions, setChatSessions] = useState<ChatSession[]>([]);
|
||||
const [currentChat, setCurrentChat] = useState<ChatSession | null>(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 (
|
||||
<Layout className={styles.ckboxLayout}>
|
||||
{/* <Button onClick={getChatInfo}>点击</Button> */}
|
||||
{contextHolder}
|
||||
{/* 左侧边栏 */}
|
||||
<SidebarMenu
|
||||
|
||||
@@ -1,7 +1,63 @@
|
||||
import { useCkChatStore } from "@/store/module/ckchat";
|
||||
import { useWebSocketStore } from "@/store/module/websocket";
|
||||
|
||||
import { loginWithToken, getChuKeBaoUserInfo, getContactList } from "./api";
|
||||
const { sendCommand } = useWebSocketStore.getState();
|
||||
import { useUserStore } from "@/store/module/user";
|
||||
const { login2 } = useUserStore.getState();
|
||||
const { connect } = useWebSocketStore.getState();
|
||||
//获取微信账户组
|
||||
export const getWechatAccountGroup = () => {
|
||||
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);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -44,7 +44,7 @@ export const useCkChatStore = createPersistStore<CkChatState>(
|
||||
// 获取账户ID
|
||||
getAccountId: () => {
|
||||
const state = useCkChatStore.getState();
|
||||
return state.userInfo?.account?.id || null;
|
||||
return Number(state.userInfo?.account?.id) || null;
|
||||
},
|
||||
|
||||
// 获取租户ID
|
||||
|
||||
@@ -80,7 +80,6 @@ export const useUserStore = createPersistStore<UserState>(
|
||||
},
|
||||
login2: token2 => {
|
||||
localStorage.setItem("token2", token2);
|
||||
console.log(token2);
|
||||
|
||||
set({ token2, isLoggedIn: true });
|
||||
},
|
||||
|
||||
@@ -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<WebSocketState>(
|
||||
};
|
||||
|
||||
// 获取用户信息
|
||||
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<WebSocketState>(
|
||||
},
|
||||
|
||||
// 发送消息
|
||||
sendMessage: (message: Omit<WebSocketMessage, "id" | "timestamp">) => {
|
||||
sendMessage: message => {
|
||||
const currentState = get();
|
||||
|
||||
if (
|
||||
@@ -179,8 +183,6 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
|
||||
|
||||
const fullMessage: WebSocketMessage = {
|
||||
...message,
|
||||
id: Date.now().toString(),
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
|
||||
try {
|
||||
@@ -204,16 +206,8 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
|
||||
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<WebSocketState>(
|
||||
});
|
||||
|
||||
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" });
|
||||
|
||||
Reference in New Issue
Block a user