2026-07-27 11:26:39 +08:00

366 lines
9.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
},
},
});