366 lines
9.8 KiB
JavaScript
Raw Permalink Normal View History

2026-07-27 11:26:39 +08:00
import { defineStore } from "pinia";
import TIM from "tim-wx-sdk";
import TIMUploadPlugin from "tim-upload-plugin";
import { generateUserSig } from "@/utils/api";
export const useIMStore = defineStore("im", {
state: () => ({
tim: null,
isSDKReady: false,
currentConversation: null,
messageList: [],
conversationList: [],
friendList: [],
userInfo: null,
isLogin: false,
}),
actions: {
// 初始化IM SDK
initIM(sdkAppId) {
// 替换为您的腾讯云IM应用SDKAppID
const SDKAppID = sdkAppId; // 请替换为您的SDKAppID
// 创建 SDK 实例
let tim = TIM.create({
SDKAppID,
});
// 设置日志级别
tim.setLogLevel(1);
// 注册上传插件
tim.registerPlugin({ "tim-upload-plugin": TIMUploadPlugin });
this.tim = tim;
// 监听事件
this.registerTIMListeners();
},
// 注册IM事件监听
registerTIMListeners() {
if (!this.tim) return;
// SDK准备就绪
this.tim.on(TIM.EVENT.SDK_READY, this.onSDKReady);
// 会话列表更新
this.tim.on(
TIM.EVENT.CONVERSATION_LIST_UPDATED,
this.onConversationListUpdated
);
// 收到新消息
this.tim.on(TIM.EVENT.MESSAGE_RECEIVED, this.onMessageReceived);
// SDK不可用
this.tim.on(TIM.EVENT.SDK_NOT_READY, this.onSDKNotReady);
// 被踢下线
this.tim.on(TIM.EVENT.KICKED_OUT, this.onKickedOut);
},
// SDK就绪处理
onSDKReady({ name }) {
console.log("TIM SDK就绪: ", name);
this.isSDKReady = true;
// 获取个人资料
this.getUserProfile();
// 获取会话列表
this.getConversationList();
// 获取好友列表
// this.getFriendList();
},
// SDK未就绪处理
onSDKNotReady({ name }) {
console.log("TIM SDK未就绪: ", name);
this.isSDKReady = false;
},
// 被踢下线处理
onKickedOut({ name }) {
console.log("被踢下线: ", name);
this.isLogin = false;
this.isSDKReady = false;
uni.showToast({
title: "您的账号已在其他设备登录",
icon: "none",
});
// 跳转到登录页
uni.reLaunch({
url: "/pages/home/home",
});
},
// 会话列表更新处理
onConversationListUpdated({ data }) {
this.conversationList = data;
},
// 接收新消息处理
onMessageReceived({ data }) {
if (this.currentConversation) {
// 如果是当前会话的消息,直接添加到消息列表
const newMessages = data.filter(
(msg) =>
msg.conversationID === this.currentConversation.conversationID
);
if (newMessages.length) {
this.messageList = [...this.messageList, ...newMessages];
}
}
},
// 延时函数
sleep(time) {
return new Promise((resolve) => setTimeout(resolve, time));
},
// 登录IM
async login(userID, retryCount = 0, maxRetries = 3, retryDelay = 1000) {
try {
const { sdkAppId, data } = await generateUserSig({
userId: userID,
});
if (!this.tim) {
this.initIM(sdkAppId);
}
//判断若已经登录,则登出
if (this.isLogin) {
await this.logout();
}
await this.tim.login({ userID, userSig: data });
this.isLogin = true;
return true;
} catch (error) {
console.error(`登录失败(第${retryCount + 1}次尝试):`, error);
// 登录失败后的重试机制
if (retryCount < maxRetries) {
console.log(`${retryDelay / 1000}秒后尝试重新登录...`);
await this.sleep(retryDelay);
// 递增重试延迟,避免频繁请求
return this.login(
userID,
retryCount + 1,
maxRetries,
retryDelay * 1.5
);
}
uni.showToast({
title: `IM登录失败请检查网络后重试`,
icon: "none",
});
return false;
}
},
// 登出IM
async logout() {
if (!this.tim) return;
try {
await this.tim.logout();
this.isLogin = false;
this.isSDKReady = false;
this.userInfo = null;
this.conversationList = [];
this.friendList = [];
this.messageList = [];
this.currentConversation = null;
return true;
} catch (error) {
console.error("登出失败:", error);
return false;
}
},
// 获取个人资料
async getUserProfile() {
if (!this.isSDKReady) return;
try {
const res = await this.tim.getMyProfile();
this.userInfo = res.data;
return res.data;
} catch (error) {
console.error("获取个人资料失败:", error);
}
},
// 获取会话列表
async getConversationList() {
if (!this.isSDKReady) return;
try {
const res = await this.tim.getConversationList();
this.conversationList = res.data.conversationList;
return this.conversationList;
} catch (error) {
console.error("获取会话列表失败:", error);
}
},
// 获取好友列表
async getFriendList() {
if (!this.isSDKReady) return;
try {
const res = await this.tim.getFriendList();
this.friendList = res.data;
return this.friendList;
} catch (error) {
console.error("获取好友列表失败:", error);
}
},
// 进入会话
async enterConversation(conversationID) {
if (!this.isSDKReady) return;
try {
// 获取会话信息
const res = await this.tim.getConversationProfile(conversationID);
this.currentConversation = res.data.conversation;
// 获取会话消息
await this.getMessageList(conversationID);
return this.currentConversation;
} catch (error) {
return false;
}
},
// 获取消息列表
async getMessageList(conversationID, count = 50, nextReqMessageID = "") {
if (!this.isSDKReady) return;
try {
const res = await this.tim.getMessageList({
conversationID,
count: 50,
nextReqMessageID,
});
if (nextReqMessageID) {
// 如果是加载更多消息,将新消息添加到现有消息列表的前面
this.messageList = [...res.data.messageList, ...this.messageList];
} else {
// 否则,替换当前消息列表
this.messageList = res.data.messageList;
}
return res.data;
} catch (error) {
console.error("获取消息列表失败:", error);
}
},
// 发送文本消息
async sendTextMessage(text, conversationID) {
if (!this.isSDKReady) return;
try {
// 创建文本消息
console.log("创建文本", conversationID);
const message = this.tim.createTextMessage({
to: conversationID.replace("C2C", ""),
conversationType: conversationID.startsWith("C2C")
? TIM.TYPES.CONV_C2C
: TIM.TYPES.CONV_GROUP,
payload: {
text,
},
});
// 发送消息
const res = await this.tim.sendMessage(message);
this.messageList.push(res.data.message);
return res.data.message;
} catch (error) {
console.error("发送文本消息失败:", error);
}
},
// 发送图片消息
async sendImageMessage(file, conversationID) {
if (!this.isSDKReady) return;
try {
// 创建图片消息
const message = this.tim.createImageMessage({
to: conversationID.replace("C2C", ""),
conversationType: conversationID.startsWith("C2C")
? TIM.TYPES.CONV_C2C
: TIM.TYPES.CONV_GROUP,
payload: {
file,
},
});
// 发送消息
const res = await this.tim.sendMessage(message);
this.messageList.push(res.data.message);
return res.data.message;
} catch (error) {
console.error("发送图片消息失败:", error);
}
},
// 更新昵称
async updateNickname(newNickname) {
if (!this.isSDKReady) return;
try {
const res = await this.tim.updateMyProfile({
nick: newNickname,
});
this.userInfo.nick = newNickname;
return res.data;
} catch (error) {
console.error("更新昵称失败:", error);
throw error;
}
},
async getImageUrl(uuid) {
if (!this.isSDKReady) return;
try {
// 假设 tim.getImageUrl 是一个有效的方法
const url = await this.tim.getImageUrl(uuid);
return url;
} catch (error) {
console.error("获取图片URL失败:", error);
throw error;
}
},
// 切换会话
async switchConversation(conversationID) {
if (!this.isSDKReady) return;
try {
// 进入新的会话
const res = await this.enterConversation(conversationID);
return res;
} catch (error) {
console.error("切换会话失败:", error);
throw error;
}
},
// 发送自定义消息(用于音视频通话信令等场景)
async sendCustomMessage(payload, conversationID) {
if (!this.isSDKReady) return;
try {
const message = this.tim.createCustomMessage({
to: conversationID.replace("C2C", ""),
conversationType: conversationID.startsWith("C2C")
? TIM.TYPES.CONV_C2C
: TIM.TYPES.CONV_GROUP,
payload,
});
const res = await this.tim.sendMessage(message);
this.messageList.push(res.data.message);
return res.data.message;
} catch (error) {
console.error("发送自定义消息失败:", error);
throw error;
}
},
},
});