mdm-im-v3 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/{FilePreview-dpnc9m3Z.js → FilePreview-Cz0KMA_m.js} +2 -2
  3. package/dist/core.es.js +2 -2
  4. package/dist/{index-CsaYx_7b.js → index-C8koozDu.js} +2 -2
  5. package/dist/{index-CNxeqkio.js → index-GiaKeCU7.js} +47 -47
  6. package/dist/{index-D5S79LNp.js → index-P9_HILzo.js} +599 -319
  7. package/dist/index.es.js +1 -1
  8. package/dist/style/index.css +1 -1
  9. package/dist-h5/{ChatHistoryH5-BhrGF5WR.js → ChatHistoryH5-CKDqKPl-.js} +2 -2
  10. package/dist-h5/{ChatPageH5-B3azJu7O.js → ChatPageH5-FXZxtcQr.js} +3 -3
  11. package/dist-h5/{ChatSettingsH5-CFr9Bn69.js → ChatSettingsH5-PackrlPt.js} +1 -1
  12. package/dist-h5/{CreateGroupH5-a16jkObH.js → CreateGroupH5-CO_ZH36_.js} +2 -2
  13. package/dist-h5/{GroupAnnouncementH5-B-Qfzoy2.js → GroupAnnouncementH5-yUDR5kYW.js} +1 -1
  14. package/dist-h5/{GroupInfoDialogH5-BHLKs62Z.js → GroupInfoDialogH5-BRk-_mEn.js} +1 -1
  15. package/dist-h5/{GroupMembersH5-D_f1RFjO.js → GroupMembersH5-BVHUF2mG.js} +1 -1
  16. package/dist-h5/{GroupNoticeH5-46ZjBe92.js → GroupNoticeH5-KA-L2h9r.js} +1 -1
  17. package/dist-h5/{MemberDetailH5-B7nlr8ZT.js → MemberDetailH5-BfAE0nx-.js} +2 -2
  18. package/dist-h5/{SearchPageH5-hYxNItvz.js → SearchPageH5-B6B_U4hW.js} +2 -2
  19. package/dist-h5/{SelectMembersH5-DQIfX_w4.js → SelectMembersH5-CrPoBnYp.js} +2 -2
  20. package/dist-h5/{imChat-Bfl2JS8Q.js → imChat-pGlpr8Vj.js} +40 -7
  21. package/dist-h5/index.es.js +2 -2
  22. package/dist-h5/{indexH5-DAnvVyZ1.js → indexH5-CCvF1MV7.js} +413 -128
  23. package/dist-h5/{indexH5-CUQe-Ize.js → indexH5-sKvS7t3k.js} +7 -3
  24. package/package.json +72 -71
  25. package/dist-h5/request-CK8gkCRf.js +0 -44
@@ -2,9 +2,77 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  import { ref, computed } from "vue";
5
- import { defineStore } from "pinia";
6
5
  import axios from "axios";
7
6
  import { ElMessage } from "element-plus";
7
+ import { defineStore } from "pinia";
8
+ function normalizeIMIdentity(config = {}) {
9
+ const version = Number(config.imIdentityVersion || 1);
10
+ const tenantID = String(config.tenantID || "");
11
+ const userID = version === 2 ? String(config.imUserID || "") : String(config.userID || "");
12
+ if (![1, 2].includes(version)) throw new Error("不支持的 IM 身份版本");
13
+ if (version === 2 && (!tenantID || !/^mdm2u_[a-f0-9]{48}$/.test(userID))) {
14
+ throw new Error("租户 IM 身份信息不完整");
15
+ }
16
+ return { imIdentityVersion: version, tenantID, userID, imUserID: version === 2 ? userID : "" };
17
+ }
18
+ function imSessionScope(config = {}) {
19
+ if (!config.userID && !config.imUserID) return "";
20
+ const identity = normalizeIMIdentity(config);
21
+ return JSON.stringify([
22
+ config.apiUrl || "",
23
+ config.wsUrl || "",
24
+ identity.tenantID,
25
+ identity.imIdentityVersion,
26
+ identity.userID,
27
+ config.platformID ?? 5
28
+ ]);
29
+ }
30
+ function imCacheNamespace(config = {}) {
31
+ if (!config.tenantID || !config.userID && !config.imUserID) return "";
32
+ return `scope2:${imSessionScope(config)}`;
33
+ }
34
+ function nextIMSession(current, input = {}) {
35
+ const merged = { ...current, ...input };
36
+ if (Number(merged.imIdentityVersion) === 2 && String(current.tenantID || "") !== String(merged.tenantID || "") && !Object.hasOwn(input, "imUserID")) {
37
+ throw new Error("切换租户必须提供目标 IM 身份");
38
+ }
39
+ const next = { ...merged, ...normalizeIMIdentity(merged) };
40
+ if (imSessionScope(current) !== imSessionScope(next)) {
41
+ for (const key of ["imToken", "satoken", "chatToken", "nickname", "faceURL", "remoteConnectUrl", "remoteConnectToken", "businessUserID", "loginCode"]) {
42
+ next[key] = Object.hasOwn(input, key) ? input[key] : "";
43
+ }
44
+ next.loginStatus = 1;
45
+ next.groupStatus = 0;
46
+ next.currentChatId = "";
47
+ next.unReadCount = 0;
48
+ next.isViewingChat = false;
49
+ }
50
+ return next;
51
+ }
52
+ function parseIMBusinessData(value) {
53
+ try {
54
+ const result = typeof value === "string" ? JSON.parse(value) : value;
55
+ return result && typeof result === "object" && !Array.isArray(result) ? result : null;
56
+ } catch {
57
+ return null;
58
+ }
59
+ }
60
+ function shouldHandleLoginNotice(notice, session) {
61
+ if (Number(session.imIdentityVersion) === 2) return false;
62
+ if (!notice || notice.event !== "LOGIN_NOTICE") return false;
63
+ if (notice.tenantID != null && String(notice.tenantID) !== String(session.tenantID)) return false;
64
+ return Boolean(notice.sendUserID && notice.imToken && session.imToken && notice.sendUserID === session.userID && notice.imToken !== session.imToken);
65
+ }
66
+ function assertIMTarget(value, kind = "user") {
67
+ const pattern = kind === "group" ? /^mdm2g_[a-f0-9]{48}$/ : /^mdm2u_[a-f0-9]{48}$/;
68
+ if (!pattern.test(String(value || ""))) throw new Error(kind === "group" ? "请先通过服务端预留租户群组身份" : "消息目标缺少租户 IM 身份");
69
+ }
70
+ function shouldHandleRemoteNotice(notice, session) {
71
+ if (!notice) return false;
72
+ if (Number(session.imIdentityVersion) !== 2) return notice.sendUserID !== session.userID;
73
+ const own = session.imUserID || session.userID;
74
+ return Boolean(own && String(notice.tenantID || "") === String(session.tenantID || "") && /^mdm2u_[a-f0-9]{48}$/.test(notice.sendIMUserID || "") && notice.recvIMUserID === own && notice.sendIMUserID !== own);
75
+ }
8
76
  const CbEvents = {
9
77
  OnConnectFailed: "OnConnectFailed",
10
78
  OnConnectSuccess: "OnConnectSuccess",
@@ -9786,6 +9854,227 @@ class EventEmitter {
9786
9854
  this.emitter.all.clear();
9787
9855
  }
9788
9856
  }
9857
+ const useChatStore = defineStore("chatMessage", {
9858
+ state: () => {
9859
+ return {
9860
+ userID: "",
9861
+ // SDK IM identity (legacy hosts still supply loginCode)
9862
+ imUserID: "",
9863
+ businessUserID: "",
9864
+ loginCode: "",
9865
+ imIdentityVersion: 1,
9866
+ nickname: "",
9867
+ // 用户昵称
9868
+ faceURL: "",
9869
+ // 用户头像
9870
+ platformID: IM_LOGIN_PLATFORM.Web,
9871
+ loginStatus: IM_LOGIN_STATUS.Logout,
9872
+ // 登录状态
9873
+ groupStatus: IM_GROUP_STATUS.Nomal,
9874
+ // 群组状态
9875
+ apiUrl: "",
9876
+ wsUrl: "",
9877
+ tenantID: "",
9878
+ satoken: "",
9879
+ // 系统Token
9880
+ imToken: "",
9881
+ // IM token
9882
+ chatToken: "",
9883
+ // 聊天token
9884
+ unReadCount: 0,
9885
+ // 本账号所有未读消息
9886
+ currentChatId: "",
9887
+ // 当前会话ID
9888
+ isFocused: true,
9889
+ // 窗口是否聚焦
9890
+ remoteConnectUrl: "",
9891
+ // 向日葵被控端连接地址
9892
+ remoteConnectToken: "",
9893
+ // 被控端连接token(session)
9894
+ isViewingChat: false
9895
+ // 是否在H5聊天详情页(控制自动标记已读)
9896
+ };
9897
+ },
9898
+ getters: {
9899
+ // 获取当前会话ID
9900
+ getCurrentChatId(state) {
9901
+ return state.currentChatId;
9902
+ },
9903
+ // 获取用户登录状态
9904
+ getLoginStatus(state) {
9905
+ return state.loginStatus;
9906
+ },
9907
+ // 获取基本地址路径
9908
+ getBaseUrl(state) {
9909
+ return state.apiUrl;
9910
+ },
9911
+ // 获取socket链接路径
9912
+ getWsUrl(state) {
9913
+ return state.wsUrl;
9914
+ },
9915
+ // 获取系统token
9916
+ getToken(state) {
9917
+ return state.satoken;
9918
+ },
9919
+ // 获取租户ID
9920
+ getTenantID(state) {
9921
+ return state.tenantID;
9922
+ },
9923
+ // 获取用户登录信息
9924
+ getUserInfo(state) {
9925
+ return {
9926
+ userID: state.userID,
9927
+ imUserID: state.imUserID,
9928
+ businessUserID: state.businessUserID,
9929
+ loginCode: state.loginCode,
9930
+ imIdentityVersion: state.imIdentityVersion,
9931
+ nickname: state.nickname,
9932
+ faceURL: state.faceURL,
9933
+ loginStatus: state.loginStatus,
9934
+ platformID: state.platformID,
9935
+ satoken: state.satoken,
9936
+ tenantID: state.tenantID,
9937
+ imToken: state.imToken,
9938
+ chatToken: state.chatToken
9939
+ };
9940
+ },
9941
+ // 获取未读消息总数
9942
+ getUnReadCount(state) {
9943
+ return state.unReadCount;
9944
+ },
9945
+ // 获取窗口是否聚焦
9946
+ getIsFocused(state) {
9947
+ return state.isFocused;
9948
+ },
9949
+ // 获取被控端连接地址
9950
+ getRemoteConnectUrl(state) {
9951
+ return state.remoteConnectUrl;
9952
+ },
9953
+ // 获取被控端连接token
9954
+ getRemoteConnectToken(state) {
9955
+ return state.remoteConnectToken;
9956
+ },
9957
+ // 获取是否在查看H5聊天详情
9958
+ getIsViewingChat(state) {
9959
+ return state.isViewingChat;
9960
+ }
9961
+ },
9962
+ actions: {
9963
+ // 设置当前会话ID
9964
+ setCurrentChatId(id) {
9965
+ this.currentChatId = id;
9966
+ },
9967
+ // 更新未读总数
9968
+ setUnReadCount(count = 0) {
9969
+ this.unReadCount = count;
9970
+ },
9971
+ // 更新用户的登录状态
9972
+ setLoginStatus(val) {
9973
+ this.loginStatus = val;
9974
+ },
9975
+ // 更新群组状态
9976
+ setGroupStatus(val) {
9977
+ this.groupStatus = val;
9978
+ },
9979
+ // 保存登录用户信息
9980
+ setUserInfo(obj) {
9981
+ const next = nextIMSession(this.$state, obj);
9982
+ this.$patch(next);
9983
+ },
9984
+ // 设置窗口聚焦状态
9985
+ setIsFocused(val) {
9986
+ this.isFocused = val;
9987
+ },
9988
+ // 设置被控端连接地址
9989
+ setRemoteConnectUrl(url) {
9990
+ this.remoteConnectUrl = url;
9991
+ },
9992
+ // 设置被控端连接token
9993
+ setRemoteConnectToken(token) {
9994
+ this.remoteConnectToken = token;
9995
+ },
9996
+ // 设置是否在查看H5聊天详情
9997
+ setIsViewingChat(val) {
9998
+ this.isViewingChat = val;
9999
+ }
10000
+ },
10001
+ persist: {
10002
+ enabled: true,
10003
+ // 开启持久化
10004
+ strategies: [
10005
+ {
10006
+ key: "MDM_CHAT_MESSAGE",
10007
+ // 存储的 key 名(默认 store id)
10008
+ storage: localStorage,
10009
+ // 存储位置(默认 localStorage)
10010
+ // HttpOnly Cookie 认证:satoken 和 imToken 不再持久化到 localStorage,仅保留在 Pinia 内存中
10011
+ paths: ["userID", "nickname", "faceURL", "platformID", "apiUrl", "wsUrl", "tenantID", "imUserID", "businessUserID", "loginCode", "imIdentityVersion"]
10012
+ }
10013
+ ]
10014
+ }
10015
+ });
10016
+ const requestInstance = axios.create({
10017
+ baseURL: "",
10018
+ timeout: 6e4,
10019
+ withCredentials: true
10020
+ // HttpOnly Cookie 认证:自动携带会话 Cookie
10021
+ });
10022
+ requestInstance.defaults.headers.post["Content-Type"] = "application/json; charset=utf-8";
10023
+ requestInstance.interceptors.request.use(
10024
+ function(config) {
10025
+ config.headers["X-Login-Type"] = "3";
10026
+ const chatStore = useChatStore();
10027
+ if (chatStore.satoken) {
10028
+ config.headers["satoken"] = chatStore.satoken;
10029
+ }
10030
+ return config;
10031
+ },
10032
+ function(error) {
10033
+ return Promise.reject(error);
10034
+ }
10035
+ );
10036
+ requestInstance.interceptors.response.use(
10037
+ function(response) {
10038
+ if ((response == null ? void 0 : response.status) == 200) {
10039
+ const code = response == null ? void 0 : response.data.code;
10040
+ if (EXIT_CODE.values.includes(code)) {
10041
+ if (EXIT_CODE[code] !== "token") {
10042
+ ElMessage.error(EXIT_CODE.label[code]);
10043
+ }
10044
+ }
10045
+ } else {
10046
+ ElMessage.error("接口出错,请检查网络后重试");
10047
+ }
10048
+ return response;
10049
+ },
10050
+ function(error) {
10051
+ return Promise.reject(error);
10052
+ }
10053
+ );
10054
+ class IMSessionChangedError extends Error {
10055
+ constructor() {
10056
+ super("IM 会话已切换,请重试");
10057
+ this.name = "IMSessionChangedError";
10058
+ }
10059
+ }
10060
+ function guardIMSDK(sdk, isCurrent) {
10061
+ const lifecycle = /* @__PURE__ */ new Set(["on", "off", "logout"]);
10062
+ return new Proxy(sdk, {
10063
+ get(target, key) {
10064
+ const value = Reflect.get(target, key);
10065
+ if (typeof value !== "function") return value;
10066
+ return (...args) => {
10067
+ if (!lifecycle.has(key) && !isCurrent()) return Promise.reject(new IMSessionChangedError());
10068
+ const result = Reflect.apply(value, target, args);
10069
+ if (!result || typeof result.then !== "function" || lifecycle.has(key)) return result;
10070
+ return result.then((data) => {
10071
+ if (!isCurrent()) throw new IMSessionChangedError();
10072
+ return data;
10073
+ });
10074
+ };
10075
+ }
10076
+ });
10077
+ }
9789
10078
  const HEX = "0123456789abcdef";
9790
10079
  function randomBytes(length) {
9791
10080
  if (typeof crypto !== "undefined" && crypto.getRandomValues) {
@@ -9819,7 +10108,9 @@ class ImKit extends EventEmitter {
9819
10108
  dataDir = "./",
9820
10109
  userID,
9821
10110
  imToken,
9822
- chatToken
10111
+ chatToken,
10112
+ imIdentityVersion = 1,
10113
+ isCurrentSession = () => true
9823
10114
  }) {
9824
10115
  super();
9825
10116
  __publicField(this, "apiUrl", "");
@@ -9843,6 +10134,11 @@ class ImKit extends EventEmitter {
9843
10134
  __publicField(this, "loginStatus", IM_LOGIN_STATUS.Logout);
9844
10135
  // 1 未登录 2 登录中 3 已登录
9845
10136
  __publicField(this, "groupStatus", IM_GROUP_STATUS.Nomal);
10137
+ this.imIdentityVersion = Number(imIdentityVersion);
10138
+ this.isCurrentSession = isCurrentSession;
10139
+ this.disposed = false;
10140
+ this.pendingGroupCreates = /* @__PURE__ */ new Map();
10141
+ this.businessApiUrl = apiUrl;
9846
10142
  this.apiUrl = `${apiUrl}/imapi`;
9847
10143
  this.wsUrl = `${wsUrl}/imws`;
9848
10144
  this.platformID = platformID;
@@ -9878,7 +10174,8 @@ class ImKit extends EventEmitter {
9878
10174
  // @openim/client-sdk和@openim/wasm-client-sdk 不需要初始化,直接调用 login 即可。
9879
10175
  initSDK() {
9880
10176
  try {
9881
- this.IMSDK = Ot();
10177
+ this.disposed = false;
10178
+ this.IMSDK = guardIMSDK(Ot(), () => !this.disposed && this.isCurrentSession());
9882
10179
  this.bindEvent();
9883
10180
  } catch (err) {
9884
10181
  console.error(err);
@@ -9918,6 +10215,7 @@ class ImKit extends EventEmitter {
9918
10215
  }
9919
10216
  // 清空即时通信实例
9920
10217
  clearSDK() {
10218
+ this.disposed = true;
9921
10219
  this.unbindEvent();
9922
10220
  this.IMSDK = null;
9923
10221
  }
@@ -10147,8 +10445,9 @@ class ImKit extends EventEmitter {
10147
10445
  console.log("请先初始化SDK");
10148
10446
  return;
10149
10447
  }
10150
- this.IMSDK.logout().then(() => {
10151
- this.getLoginStatus();
10448
+ return this.IMSDK.logout().then(() => {
10449
+ this.loginStatus = IM_LOGIN_STATUS.Logout;
10450
+ this.emit("updateStatus", this.loginStatus);
10152
10451
  return true;
10153
10452
  }).catch((error) => {
10154
10453
  console.log("IM登出异常:", error);
@@ -10821,6 +11120,10 @@ class ImKit extends EventEmitter {
10821
11120
  }
10822
11121
  // 发送消息,发送通过 create***Message 创建的消息,offlinePushInfo-离线消息体,groupID-发送单聊消息时传空字符串
10823
11122
  async sendMessage({ recvID, groupID, offlinePushInfo, message }, operationID = uuidv4()) {
11123
+ if (this.imIdentityVersion === 2) {
11124
+ if (groupID) assertIMTarget(groupID, "group");
11125
+ else assertIMTarget(recvID);
11126
+ }
10824
11127
  try {
10825
11128
  const res = await this.IMSDK.sendMessage({ recvID, groupID, offlinePushInfo, message }, operationID);
10826
11129
  if (res.data) {
@@ -10995,9 +11298,26 @@ class ImKit extends EventEmitter {
10995
11298
  * @param {String} operationID
10996
11299
  */
10997
11300
  async createGroup({ groupInfo, memberUserIDs, ownerUserID, adminUserIDs }, operationID = uuidv4()) {
10998
- var _a;
11301
+ var _a, _b, _c;
11302
+ if (this.imIdentityVersion === 2) {
11303
+ if (this.disposed || !this.isCurrentSession()) throw new IMSessionChangedError();
11304
+ if (ownerUserID !== this.userID) throw new Error("群主必须是当前用户");
11305
+ if (adminUserIDs == null ? void 0 : adminUserIDs.length) throw new Error("请在建群后设置管理员");
11306
+ const spec = JSON.stringify([groupInfo == null ? void 0 : groupInfo.groupName, ownerUserID, [...memberUserIDs || []].sort()]);
11307
+ const requestID = String((groupInfo == null ? void 0 : groupInfo.groupID) || this.pendingGroupCreates.get(spec) || operationID);
11308
+ this.pendingGroupCreates.set(spec, requestID);
11309
+ const result = await requestInstance.post(`${this.businessApiUrl}/api/v1/openim/createTenantGroup`, {
11310
+ requestID,
11311
+ groupName: groupInfo == null ? void 0 : groupInfo.groupName,
11312
+ members: memberUserIDs || []
11313
+ });
11314
+ if (this.disposed || !this.isCurrentSession()) throw new IMSessionChangedError();
11315
+ if (((_a = result.data) == null ? void 0 : _a.code) !== 200) throw new Error(((_b = result.data) == null ? void 0 : _b.msg) || "建群失败");
11316
+ this.pendingGroupCreates.delete(spec);
11317
+ return true;
11318
+ }
10999
11319
  try {
11000
- const res = await ((_a = this.IMSDK) == null ? void 0 : _a.createGroup(
11320
+ const res = await ((_c = this.IMSDK) == null ? void 0 : _c.createGroup(
11001
11321
  {
11002
11322
  groupInfo,
11003
11323
  memberUserIDs,
@@ -11066,6 +11386,10 @@ class ImKit extends EventEmitter {
11066
11386
  * @param {String} operationID
11067
11387
  */
11068
11388
  async inviteUserToGroup({ groupID, userIDList: userIDList2, reason }, operationID = uuidv4()) {
11389
+ if (this.imIdentityVersion === 2) {
11390
+ assertIMTarget(groupID, "group");
11391
+ for (const id of userIDList2 || []) assertIMTarget(id);
11392
+ }
11069
11393
  if (!groupID || !this.IMSDK) return;
11070
11394
  try {
11071
11395
  const res = await this.IMSDK.inviteUserToGroup({ groupID, userIDList: userIDList2, reason }, operationID);
@@ -11412,165 +11736,6 @@ class ImKit extends EventEmitter {
11412
11736
  }
11413
11737
  }
11414
11738
  }
11415
- const useChatStore = defineStore("chatMessage", {
11416
- state: () => {
11417
- return {
11418
- userID: "",
11419
- // 用户ID
11420
- nickname: "",
11421
- // 用户昵称
11422
- faceURL: "",
11423
- // 用户头像
11424
- platformID: IM_LOGIN_PLATFORM.Web,
11425
- loginStatus: IM_LOGIN_STATUS.Logout,
11426
- // 登录状态
11427
- groupStatus: IM_GROUP_STATUS.Nomal,
11428
- // 群组状态
11429
- apiUrl: "",
11430
- wsUrl: "",
11431
- tenantID: "",
11432
- satoken: "",
11433
- // 系统Token
11434
- imToken: "",
11435
- // IM token
11436
- chatToken: "",
11437
- // 聊天token
11438
- unReadCount: 0,
11439
- // 本账号所有未读消息
11440
- currentChatId: "",
11441
- // 当前会话ID
11442
- isFocused: true,
11443
- // 窗口是否聚焦
11444
- remoteConnectUrl: "",
11445
- // 向日葵被控端连接地址
11446
- remoteConnectToken: "",
11447
- // 被控端连接token(session)
11448
- isViewingChat: false
11449
- // 是否在H5聊天详情页(控制自动标记已读)
11450
- };
11451
- },
11452
- getters: {
11453
- // 获取当前会话ID
11454
- getCurrentChatId(state) {
11455
- return state.currentChatId;
11456
- },
11457
- // 获取用户登录状态
11458
- getLoginStatus(state) {
11459
- return state.loginStatus;
11460
- },
11461
- // 获取基本地址路径
11462
- getBaseUrl(state) {
11463
- return state.apiUrl;
11464
- },
11465
- // 获取socket链接路径
11466
- getWsUrl(state) {
11467
- return state.wsUrl;
11468
- },
11469
- // 获取系统token
11470
- getToken(state) {
11471
- return state.satoken;
11472
- },
11473
- // 获取租户ID
11474
- getTenantID(state) {
11475
- return state.tenantID;
11476
- },
11477
- // 获取用户登录信息
11478
- getUserInfo(state) {
11479
- return {
11480
- userID: state.userID,
11481
- nickname: state.nickname,
11482
- faceURL: state.faceURL,
11483
- loginStatus: state.loginStatus,
11484
- platformID: state.platformID,
11485
- satoken: state.satoken,
11486
- tenantID: state.tenantID,
11487
- imToken: state.imToken,
11488
- chatToken: state.chatToken
11489
- };
11490
- },
11491
- // 获取未读消息总数
11492
- getUnReadCount(state) {
11493
- return state.unReadCount;
11494
- },
11495
- // 获取窗口是否聚焦
11496
- getIsFocused(state) {
11497
- return state.isFocused;
11498
- },
11499
- // 获取被控端连接地址
11500
- getRemoteConnectUrl(state) {
11501
- return state.remoteConnectUrl;
11502
- },
11503
- // 获取被控端连接token
11504
- getRemoteConnectToken(state) {
11505
- return state.remoteConnectToken;
11506
- },
11507
- // 获取是否在查看H5聊天详情
11508
- getIsViewingChat(state) {
11509
- return state.isViewingChat;
11510
- }
11511
- },
11512
- actions: {
11513
- // 设置当前会话ID
11514
- setCurrentChatId(id) {
11515
- this.currentChatId = id;
11516
- },
11517
- // 更新未读总数
11518
- setUnReadCount(count = 0) {
11519
- this.unReadCount = count;
11520
- },
11521
- // 更新用户的登录状态
11522
- setLoginStatus(val) {
11523
- this.loginStatus = val;
11524
- },
11525
- // 更新群组状态
11526
- setGroupStatus(val) {
11527
- this.groupStatus = val;
11528
- },
11529
- // 保存登录用户信息
11530
- setUserInfo(obj) {
11531
- this.userID = (obj == null ? void 0 : obj.userID) || this.userID;
11532
- this.nickname = (obj == null ? void 0 : obj.nickname) || this.nickname;
11533
- this.faceURL = (obj == null ? void 0 : obj.faceURL) || this.faceURL;
11534
- this.imToken = (obj == null ? void 0 : obj.imToken) || this.imToken;
11535
- this.chatToken = (obj == null ? void 0 : obj.chatToken) || this.chatToken;
11536
- this.satoken = (obj == null ? void 0 : obj.satoken) || this.satoken;
11537
- this.apiUrl = (obj == null ? void 0 : obj.apiUrl) || this.apiUrl;
11538
- this.wsUrl = (obj == null ? void 0 : obj.wsUrl) || this.wsUrl;
11539
- this.tenantID = (obj == null ? void 0 : obj.tenantID) || this.tenantID;
11540
- this.platformID = obj.platformID || this.platformID;
11541
- },
11542
- // 设置窗口聚焦状态
11543
- setIsFocused(val) {
11544
- this.isFocused = val;
11545
- },
11546
- // 设置被控端连接地址
11547
- setRemoteConnectUrl(url) {
11548
- this.remoteConnectUrl = url;
11549
- },
11550
- // 设置被控端连接token
11551
- setRemoteConnectToken(token) {
11552
- this.remoteConnectToken = token;
11553
- },
11554
- // 设置是否在查看H5聊天详情
11555
- setIsViewingChat(val) {
11556
- this.isViewingChat = val;
11557
- }
11558
- },
11559
- persist: {
11560
- enabled: true,
11561
- // 开启持久化
11562
- strategies: [
11563
- {
11564
- key: "MDM_CHAT_MESSAGE",
11565
- // 存储的 key 名(默认 store id)
11566
- storage: localStorage,
11567
- // 存储位置(默认 localStorage)
11568
- // HttpOnly Cookie 认证:satoken 和 imToken 不再持久化到 localStorage,仅保留在 Pinia 内存中
11569
- paths: ["userID", "nickname", "faceURL", "platformID", "apiUrl", "wsUrl", "tenantID"]
11570
- }
11571
- ]
11572
- }
11573
- });
11574
11739
  const userList = ref([]);
11575
11740
  const userIDList = ref([]);
11576
11741
  const userOnlineStatus = ref({});
@@ -11608,7 +11773,12 @@ const useUsers = () => {
11608
11773
  const getAllUserStatus = () => {
11609
11774
  return userOnlineStatus.value;
11610
11775
  };
11611
- return { updateUserList, getUserIds, updateUserStatus, getCurrentUserInfo, getAllUserStatus, getUserStatus };
11776
+ const resetUsers = () => {
11777
+ userList.value = [];
11778
+ userIDList.value = [];
11779
+ userOnlineStatus.value = {};
11780
+ };
11781
+ return { resetUsers, updateUserList, getUserIds, updateUserStatus, getCurrentUserInfo, getAllUserStatus, getUserStatus };
11612
11782
  };
11613
11783
  function getDefaultExportFromCjs(x3) {
11614
11784
  return x3 && x3.__esModule && Object.prototype.hasOwnProperty.call(x3, "default") ? x3["default"] : x3;
@@ -36257,7 +36427,7 @@ const toPinyin = (text) => {
36257
36427
  const conversationList = ref([]);
36258
36428
  const skipSortIds = /* @__PURE__ */ new Set();
36259
36429
  const currentConversation = ref({});
36260
- ref([]);
36430
+ const currentConversationUsers = ref([]);
36261
36431
  const useConversations = () => {
36262
36432
  const chatMessage = useChatStore();
36263
36433
  const baseUrl = chatMessage.getBaseUrl;
@@ -36446,6 +36616,8 @@ const useConversations = () => {
36446
36616
  if (id) skipSortIds.add(id);
36447
36617
  };
36448
36618
  const clearConversationList = () => {
36619
+ skipSortIds.clear();
36620
+ currentConversationUsers.value = [];
36449
36621
  conversationList.value = [];
36450
36622
  currentConversation.value = {};
36451
36623
  chatMessage.setUnReadCount(0);
@@ -37141,7 +37313,14 @@ const useMsgList = () => {
37141
37313
  }
37142
37314
  return obj.sessionType === IM_CVS_TYPE.Group ? `${obj.senderNickname}: [未知消息]` : `${obj.senderNickname}发送了消息`;
37143
37315
  };
37316
+ const clearMessageList = () => {
37317
+ messageList.value = [];
37318
+ startClientMsgID.value = "";
37319
+ isLastMessage.value = true;
37320
+ isFirstMessage.value = false;
37321
+ };
37144
37322
  return {
37323
+ clearMessageList,
37145
37324
  messageList,
37146
37325
  startClientMsgID,
37147
37326
  isLastMessage,
@@ -37322,7 +37501,7 @@ const useBurnAfterReading = () => {
37322
37501
  const origin = Number(startAt) || Date.now();
37323
37502
  const deadline = origin + duration * 1e3;
37324
37503
  if (deadline <= Date.now()) {
37325
- setTimeout(() => runHandlers(conversationID, msg.clientMsgID), 0);
37504
+ timers.set(key, setTimeout(() => fireBurn(conversationID, msg.clientMsgID), 0));
37326
37505
  return;
37327
37506
  }
37328
37507
  deadlines.set(key, deadline);
@@ -39575,13 +39754,14 @@ async function clearCache(userID) {
39575
39754
  function useMessageCache() {
39576
39755
  const chatMessage = useChatStore();
39577
39756
  function _getUserID() {
39578
- return chatMessage.userID || "";
39757
+ return imCacheNamespace(chatMessage);
39579
39758
  }
39580
39759
  async function loadConversationsFromCache() {
39581
39760
  const userID = _getUserID();
39582
39761
  if (!userID) return null;
39583
39762
  try {
39584
39763
  const list = await loadConversations(userID);
39764
+ if (userID !== _getUserID()) return null;
39585
39765
  if (list && Array.isArray(list) && list.length > 0) {
39586
39766
  console.log(
39587
39767
  `[MessageCache] Loaded ${list.length} conversations from IndexedDB cache`
@@ -39609,6 +39789,7 @@ function useMessageCache() {
39609
39789
  if (!userID || !conversationID) return null;
39610
39790
  try {
39611
39791
  const list = await loadMessages(userID, conversationID);
39792
+ if (userID !== _getUserID()) return null;
39612
39793
  if (list && Array.isArray(list) && list.length > 0) {
39613
39794
  console.log(
39614
39795
  `[MessageCache] Loaded ${list.length} messages for ${conversationID} from IndexedDB cache`
@@ -39652,6 +39833,19 @@ function useMessageCache() {
39652
39833
  const mittBus = mitt();
39653
39834
  const newMsgAudioUrl = "data:audio/mpeg;base64,SUQzAwAAAAAgAFRJVDMAAAAYAAAA1b6zpMvYssQoc2MuY2hpbmF6LmNvbSlUUFVCAAAAGAAAANW+s6TL2LLEKHNjLmNoaW5hei5jb20pV09BUgAAABcAANW+s6TL2LLEKHNjLmNoaW5hei5jb20pVEVOQwAAABgAAADVvrOky9iyxChzYy5jaGluYXouY29tKVRBTEIAAAAYAAAA1b6zpMvYssQoc2MuY2hpbmF6LmNvbSlUWUVSAAAABQAAADIwMjBUUEUyAAAAGAAAANW+s6TL2LLEKHNjLmNoaW5hei5jb20pVElUMgAAABgAAADVvrOky9iyxChzYy5jaGluYXouY29tKVRDT04AAAAYAAAA1b6zpMvYssQoc2MuY2hpbmF6LmNvbSlDT01NAAAAHAAAAGNoaQDVvrOky9iyxChzYy5jaGluYXouY29tKVRQRTEAAAAYAAAA1b6zpMvYssQoc2MuY2hpbmF6LmNvbSkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABJRDMEAAAAADYkVFhYWAAAAAsAAANUREFUADMwMDYAVFhYWAAAAAsAAANUSU1FADIxMzEAVFhYWAAAAAoAAANjb21tZW50AABQUklWAAA1OQAAWE1QADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+Cjx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQzIDc5LjE2MTIxMCwgMjAxNy8wOC8xMS0xMDoyODozNiAgICAgICAgIj4KIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIgogICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgeG1sbnM6eG1wRE09Imh0dHA6Ly9ucy5hZG9iZS5jb20veG1wLzEuMC9EeW5hbWljTWVkaWEvIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6Y3JlYXRvckF0b209Imh0dHA6Ly9ucy5hZG9iZS5jb20vY3JlYXRvckF0b20vMS4wLyIKICAgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3YjdlYjE0OC03ZTllLTA3NDctYTNlNS05NzlmN2IzZTQ4ODEiCiAgIHhtcE1NOkRvY3VtZW50SUQ9ImU4YTMzOWUyLWI5YjQtM2I5MC02OTFkLWMwZWMwMDAwMDAzZCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjM2ZDgxZDUxLWYxM2QtMWQ0MS1hODYxLWIxZTlmZDEyMzgxOCIKICAgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMC0wNi0zMFQyMTozMTozNCswODowMCIKICAgeG1wOk1vZGlmeURhdGU9IjIwMjAtMDYtMzBUMjE6MzE6MzQrMDg6MDAiCiAgIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUHJlbWllcmUgUHJvIENDIDIwMTguMCAoV2luZG93cykiCiAgIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTA2LTMwVDIxOjMxOjA0KzA4OjAwIgogICB4bXBETTphdWRpb1NhbXBsZVJhdGU9Ii0xIgogICB4bXBETTphdWRpb1NhbXBsZVR5cGU9IjE2SW50IgogICB4bXBETTphdWRpb0NoYW5uZWxUeXBlPSJTdGVyZW8iCiAgIHhtcERNOnN0YXJ0VGltZVNjYWxlPSIzMDAwMCIKICAgeG1wRE06c3RhcnRUaW1lU2FtcGxlU2l6ZT0iMTAwMSIKICAgZGM6Zm9ybWF0PSJNUDMiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0iZDEwNTQ1NzMtNjlmMS02Y2M2LTJhYTItNzk0ZDAwMDAwMDZhIgogICAgICBzdEV2dDp3aGVuPSIyMDIwLTA2LTMwVDIxOjMxOjM0KzA4OjAwIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQcmVtaWVyZSBQcm8gQ0MgMjAxOC4wIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjIwYWNhNWE3LTAwMzQtNDM0OC05ZWQ4LTBlMWY3Y2IwOGVhZCIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMC0wNi0zMFQyMTozMTozNCswODowMCIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUHJlbWllcmUgUHJvIENDIDIwMTguMCAoV2luZG93cykiLz4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ZmYxY2M1NmItMmUyMS1kMTRlLThhMGEtYTZlYWVjY2ZjODVmIgogICAgICBzdEV2dDp3aGVuPSIyMDIwLTA2LTMwVDIxOjMxOjM0KzA4OjAwIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQcmVtaWVyZSBQcm8gQ0MgMjAxOC4wIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo3YjdlYjE0OC03ZTllLTA3NDctYTNlNS05NzlmN2IzZTQ4ODEiCiAgICAgIHN0RXZ0OndoZW49IjIwMjAtMDYtMzBUMjE6MzE6MzQrMDg6MDAiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFByZW1pZXJlIFBybyBDQyAyMDE4LjAgKFdpbmRvd3MpIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvbWV0YWRhdGEiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogICA8eG1wTU06SW5ncmVkaWVudHM+CiAgICA8cmRmOkJhZz4KICAgICA8cmRmOmxpCiAgICAgIHN0UmVmOmluc3RhbmNlSUQ9IjBmODZjODFiLTgxYzAtOTY2Mi1lNGZlLTcyOTMwMDAwMDA2YSIKICAgICAgc3RSZWY6ZG9jdW1lbnRJRD0iZjNjYTE3ZDItZjhlNi1lNjY1LTMyZmEtYTI3ZDAwMDAwMDNkIgogICAgICBzdFJlZjpmcm9tUGFydD0idGltZTo1MDU1NzM4NjQ5NTBmMjU0MDE2MDAwMDAwZDIwOTIwMjk3ODYwMGYyNTQwMTYwMDAwMDAiCiAgICAgIHN0UmVmOnRvUGFydD0idGltZTowZDIwOTIwMjk3ODYwMGYyNTQwMTYwMDAwMDAiCiAgICAgIHN0UmVmOmZpbGVQYXRoPSLlvq7kv6HmnaXkv6Hmga8ubXA0IgogICAgICBzdFJlZjptYXNrTWFya2Vycz0iTm9uZSIvPgogICAgPC9yZGY6QmFnPgogICA8L3htcE1NOkluZ3JlZGllbnRzPgogICA8eG1wTU06UGFudHJ5PgogICAgPHJkZjpCYWc+CiAgICAgPHJkZjpsaT4KICAgICAgPHJkZjpEZXNjcmlwdGlvbgogICAgICAgeG1wOkNyZWF0ZURhdGU9IjE5MDQtMDEtMDFUMDA6MDBaIgogICAgICAgeG1wOk1vZGlmeURhdGU9IjIwMjAtMDYtMzBUMjE6MzA6MzQrMDg6MDAiCiAgICAgICB4bXA6TWV0YWRhdGFEYXRlPSIyMDIwLTA2LTMwVDIxOjMwOjM0KzA4OjAwIgogICAgICAgeG1wRE06bG9nQ29tbWVudD0i5pys6KeG6aKR55Sx5rmW5Y2X5LiA5ZSv5L+h5oGv56eR5oqA5byA5Y+R55qERVblvZXlsY/ova/ku7blvZXliLbvvIx3d3cuaWV3YXkuY24iCiAgICAgICB4bXBNTTpJbnN0YW5jZUlEPSIwZjg2YzgxYi04MWMwLTk2NjItZTRmZS03MjkzMDAwMDAwNmEiCiAgICAgICB4bXBNTTpEb2N1bWVudElEPSJmM2NhMTdkMi1mOGU2LWU2NjUtMzJmYS1hMjdkMDAwMDAwM2QiCiAgICAgICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6OTk4YTUwOGUtY2IxMC01ODQ1LWI3YmItYzBhMTg2Yjk5YmJkIj4KICAgICAgPHhtcERNOmR1cmF0aW9uCiAgICAgICB4bXBETTp2YWx1ZT0iMTAyMTkiCiAgICAgICB4bXBETTpzY2FsZT0iMS8xMDAwIi8+CiAgICAgIDxkYzp0aXRsZT4KICAgICAgIDxyZGY6QWx0PgogICAgICAgIDxyZGY6bGkgeG1sOmxhbmc9IngtZGVmYXVsdCI+RVblvZXlsY8zLjkuN+i9r+S7tuW9leWItjwvcmRmOmxpPgogICAgICAgPC9yZGY6QWx0PgogICAgICA8L2RjOnRpdGxlPgogICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgIDxyZGY6U2VxPgogICAgICAgIDxyZGY6bGkKICAgICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0iMGY4NmM4MWItODFjMC05NjYyLWU0ZmUtNzI5MzAwMDAwMDZhIgogICAgICAgICBzdEV2dDp3aGVuPSIyMDIwLTA2LTMwVDIxOjMwOjM0KzA4OjAwIgogICAgICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQcmVtaWVyZSBQcm8gQ0MgMjAxOC4wIChXaW5kb3dzKSIKICAgICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIvPgogICAgICAgPC9yZGY6U2VxPgogICAgICA8L3htcE1NOkhpc3Rvcnk+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgIDwvcmRmOmxpPgogICAgPC9yZGY6QmFnPgogICA8L3htcE1NOlBhbnRyeT4KICAgPHhtcE1NOkRlcml2ZWRGcm9tCiAgICBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjIwYWNhNWE3LTAwMzQtNDM0OC05ZWQ4LTBlMWY3Y2IwOGVhZCIKICAgIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MjBhY2E1YTctMDAzNC00MzQ4LTllZDgtMGUxZjdjYjA4ZWFkIgogICAgc3RSZWY6b3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjIwYWNhNWE3LTAwMzQtNDM0OC05ZWQ4LTBlMWY3Y2IwOGVhZCIvPgogICA8Y3JlYXRvckF0b206d2luZG93c0F0b20KICAgIGNyZWF0b3JBdG9tOmV4dGVuc2lvbj0iLnBycHJvaiIKICAgIGNyZWF0b3JBdG9tOmludm9jYXRpb25GbGFncz0iL0wiCiAgICBjcmVhdG9yQXRvbTp1bmNQcm9qZWN0UGF0aD0iXFw/XEM6XFVzZXJzXEFkbWluaXN0cmF0b3JcRGVza3RvcFzpn7PmlYgucHJwcm9qIi8+CiAgIDxjcmVhdG9yQXRvbTptYWNBdG9tCiAgICBjcmVhdG9yQXRvbTphcHBsaWNhdGlvbkNvZGU9IjEzNDc0NDk0NTUiCiAgICBjcmVhdG9yQXRvbTppbnZvY2F0aW9uQXBwbGVFdmVudD0iMTEyOTQ2ODAxOCIvPgogICA8eG1wRE06cHJvamVjdFJlZgogICAgeG1wRE06dHlwZT0ibW92aWUiLz4KICAgPHhtcERNOmR1cmF0aW9uCiAgICB4bXBETTp2YWx1ZT0iMjQiCiAgICB4bXBETTpzY2FsZT0iMTAwMS8zMDAwMCIvPgogICA8eG1wRE06c3RhcnRUaW1lY29kZQogICAgeG1wRE06dGltZUZvcm1hdD0iMjk5N0Ryb3BUaW1lY29kZSIKICAgIHhtcERNOnRpbWVWYWx1ZT0iMDA7MDA7MDA7MDAiLz4KICAgPHhtcERNOmFsdFRpbWVjb2RlCiAgICB4bXBETTp0aW1lVmFsdWU9IjAwOzAwOzAwOzAwIgogICAgeG1wRE06dGltZUZvcm1hdD0iMjk5N0Ryb3BUaW1lY29kZSIvPgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAg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R+ysrWhKgCe0AAAE////qEyAWeDSGdWZw2wAAAAAAA7PDy2vdviCQp8RAEQmECDyBc0BSO/M6dMN+qqSJlakAAgAYNLPMBcAqVkgNNRfSGxEAVUdCVoDEYqqM/kx96JCmFQDo5y2hvcRYcEUqljw70MeUb1TjyqNJFYy0te9HIr9amt56hKwQlBiAAOqUP+gJNVXC8qDUFX/yj2/T///9cUqAUFriUAu//uUZOiAAs400H1poAomobnNpAgBFw0hSfm8AkCqBqi/DDABgrUeDsQ1TEFNRTMuMTAwVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVMQU1FMy4xMDBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//tUZOSD8lwZSU8kYAAbgTk54YAAAWwBJwAAACAAAD/AAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//sUZOGP8AAAf4AAAAgAAA/wAAABAAABpAAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV";
39654
39835
  let imInstance = null;
39836
+ let failedLogoutClient = null;
39837
+ let sessionRevision = 0;
39838
+ let sessionQueue = Promise.resolve();
39839
+ let pendingSessionKey = "";
39840
+ const subscribedStores = /* @__PURE__ */ new WeakSet();
39841
+ let activeSessionScope = "";
39842
+ let reloginTimer = null;
39843
+ const enqueueSession = (operation) => {
39844
+ const result = sessionQueue.then(operation, operation);
39845
+ sessionQueue = result.catch(() => {
39846
+ });
39847
+ return result;
39848
+ };
39655
39849
  let initPromise = null;
39656
39850
  let httpAuthBroken = false;
39657
39851
  let syncFinished = false;
@@ -39671,7 +39865,8 @@ const resolveSyncWaiters = (ok) => {
39671
39865
  };
39672
39866
  const resetSyncState = () => {
39673
39867
  syncFinished = false;
39674
- syncWaiters = [];
39868
+ const waiters = syncWaiters.splice(0);
39869
+ waiters.forEach((done) => done(false));
39675
39870
  };
39676
39871
  const buildConversationFromMessage = (msg, selfUserID) => {
39677
39872
  if (!msg) return null;
@@ -39749,13 +39944,14 @@ const useMessage = (config = {}) => {
39749
39944
  }
39750
39945
  const loginStatus = computed(() => messageStore.loginStatus);
39751
39946
  let msgAudioEl = null;
39947
+ let initTimer = null;
39752
39948
  const getMsgAudio = () => {
39753
39949
  if (!msgAudioEl) {
39754
39950
  msgAudioEl = new Audio(newMsgAudioUrl);
39755
39951
  }
39756
39952
  return msgAudioEl;
39757
39953
  };
39758
- const { updateUserStatus } = useUsers();
39954
+ const { updateUserStatus, resetUsers } = useUsers();
39759
39955
  const {
39760
39956
  conversationList: conversationList2,
39761
39957
  currentConversation: currentConversation2,
@@ -39767,6 +39963,7 @@ const useMessage = (config = {}) => {
39767
39963
  } = useConversations();
39768
39964
  const {
39769
39965
  messageList: messageList2,
39966
+ clearMessageList,
39770
39967
  updateMessageList,
39771
39968
  updateMessageIsRead,
39772
39969
  handleMessage,
@@ -39781,6 +39978,8 @@ const useMessage = (config = {}) => {
39781
39978
  onBurn(async (conversationID, clientMsgID) => {
39782
39979
  var _a;
39783
39980
  if (!conversationID || !clientMsgID) return;
39981
+ const burnScope = imSessionScope(messageStore);
39982
+ const burnRevision = sessionRevision;
39784
39983
  const inCurrentList = messageList2.value.some((item) => item.clientMsgID === clientMsgID);
39785
39984
  if (inCurrentList) deleteMessageById(clientMsgID);
39786
39985
  try {
@@ -39788,6 +39987,7 @@ const useMessage = (config = {}) => {
39788
39987
  } catch (error) {
39789
39988
  console.error("[IM] 删除焚毁消息失败:", error);
39790
39989
  }
39990
+ if (burnRevision !== sessionRevision || burnScope !== imSessionScope(messageStore)) return;
39791
39991
  if (inCurrentList) {
39792
39992
  const rest = JSON.parse(JSON.stringify(messageList2.value));
39793
39993
  saveMessagesToCache(conversationID, rest);
@@ -39797,6 +39997,7 @@ const useMessage = (config = {}) => {
39797
39997
  }
39798
39998
  try {
39799
39999
  const cached = await loadMessagesFromCache(conversationID);
40000
+ if (burnRevision !== sessionRevision || burnScope !== imSessionScope(messageStore)) return;
39800
40001
  if ((_a = cached == null ? void 0 : cached.list) == null ? void 0 : _a.length) {
39801
40002
  const rest = cached.list.filter((item) => item.clientMsgID !== clientMsgID);
39802
40003
  saveMessagesToCache(conversationID, rest);
@@ -39823,7 +40024,10 @@ const useMessage = (config = {}) => {
39823
40024
  const getUnReadMessageCount = async (bool = false) => {
39824
40025
  if (bool) {
39825
40026
  if (!imInstance) return;
40027
+ const countScope = imSessionScope(messageStore);
40028
+ const countRevision = sessionRevision;
39826
40029
  const count = await (imInstance == null ? void 0 : imInstance.getTotalUnreadMsgCount());
40030
+ if (countRevision !== sessionRevision || countScope !== imSessionScope(messageStore)) return;
39827
40031
  messageStore.setUnReadCount(count || 0);
39828
40032
  } else {
39829
40033
  const count = conversationList2.value.reduce((pre, cur) => {
@@ -39853,47 +40057,90 @@ const useMessage = (config = {}) => {
39853
40057
  }
39854
40058
  return bool;
39855
40059
  };
39856
- const initIMSDK = async (force = false) => {
39857
- if (initPromise) return initPromise;
39858
- const sameSession = !force && !!imInstance && messageStore.loginStatus === IM_LOGIN_STATUS.Logged && imInstance.userID === String(messageStore.userID || "") && imInstance.imToken === messageStore.imToken && imInstance.apiUrl === `${messageStore.apiUrl}/imapi` && imInstance.wsUrl === `${messageStore.wsUrl}/imws`;
39859
- if (sameSession) {
39860
- window["imInstance"] = imInstance;
39861
- return true;
39862
- }
39863
- initPromise = (async () => {
39864
- if (messageStore.loginStatus === IM_LOGIN_STATUS.Logged) {
39865
- await clearInstance();
40060
+ const disposeInstance = async (clearData = true) => {
40061
+ if (reloginTimer) clearTimeout(reloginTimer);
40062
+ reloginTimer = null;
40063
+ if (initTimer) clearTimeout(initTimer);
40064
+ initTimer = null;
40065
+ unbindMessageEvent();
40066
+ cancelAllBurns();
40067
+ const previous = imInstance || failedLogoutClient;
40068
+ previous == null ? void 0 : previous.removeAllListeners();
40069
+ let loggedOut = false;
40070
+ try {
40071
+ const result = await (previous == null ? void 0 : previous.logout());
40072
+ if (result === false) throw new Error("IM 退出失败,请重试后再切换");
40073
+ loggedOut = true;
40074
+ } catch (error) {
40075
+ failedLogoutClient = previous;
40076
+ throw error;
40077
+ } finally {
40078
+ if (loggedOut) {
40079
+ previous == null ? void 0 : previous.clearSDK();
40080
+ if (failedLogoutClient === previous) failedLogoutClient = null;
39866
40081
  }
40082
+ if (imInstance === previous) imInstance = null;
40083
+ if (typeof window !== "undefined" && window.imInstance === previous) window.imInstance = null;
39867
40084
  resetSyncState();
39868
- if (!imInstance) {
39869
- imInstance = new ImKit({
39870
- userID: messageStore.userID,
39871
- imToken: messageStore.imToken,
39872
- chatToken: messageStore.chatToken,
39873
- apiUrl: messageStore.apiUrl,
39874
- wsUrl: messageStore.wsUrl
39875
- });
39876
- } else {
39877
- imInstance.userID = String(messageStore.userID || "");
39878
- imInstance.imToken = messageStore.imToken;
39879
- imInstance.chatToken = messageStore.chatToken;
39880
- imInstance.apiUrl = `${messageStore.apiUrl}/imapi`;
39881
- imInstance.wsUrl = `${messageStore.wsUrl}/imws`;
40085
+ if (clearData) {
40086
+ clearConversationList();
40087
+ clearMessageList();
40088
+ resetUsers();
40089
+ messageStore.currentChatId = "";
40090
+ messageStore.remoteConnectUrl = "";
40091
+ messageStore.remoteConnectToken = "";
40092
+ messageStore.isViewingChat = false;
40093
+ }
40094
+ messageStore.setLoginStatus(IM_LOGIN_STATUS.Logout);
40095
+ }
40096
+ };
40097
+ const initIMSDK = async (force = false) => {
40098
+ const snapshot = { ...messageStore.$state, ...normalizeIMIdentity(messageStore) };
40099
+ const scope = imSessionScope(snapshot);
40100
+ if (!scope || !snapshot.imToken) return false;
40101
+ const key = JSON.stringify([scope, snapshot.imToken]);
40102
+ if (initPromise && pendingSessionKey === key) return initPromise;
40103
+ const sameSession = !force && imInstance && activeSessionScope === scope && messageStore.loginStatus === IM_LOGIN_STATUS.Logged && imInstance.imToken === snapshot.imToken;
40104
+ if (sameSession && !initPromise) return true;
40105
+ const revision = ++sessionRevision;
40106
+ pendingSessionKey = key;
40107
+ const operation = enqueueSession(async () => {
40108
+ if (revision !== sessionRevision || imSessionScope(messageStore) !== scope) return false;
40109
+ await disposeInstance(activeSessionScope !== scope);
40110
+ if (revision !== sessionRevision || imSessionScope(messageStore) !== scope) return false;
40111
+ activeSessionScope = scope;
40112
+ const client = new ImKit({
40113
+ userID: snapshot.userID,
40114
+ imToken: snapshot.imToken,
40115
+ chatToken: snapshot.chatToken,
40116
+ imIdentityVersion: snapshot.imIdentityVersion,
40117
+ apiUrl: snapshot.apiUrl,
40118
+ wsUrl: snapshot.wsUrl,
40119
+ platformID: snapshot.platformID,
40120
+ isCurrentSession: () => revision === sessionRevision && imSessionScope(messageStore) === scope
40121
+ });
40122
+ imInstance = client;
40123
+ client.initSDK();
40124
+ bindMessageEvent(client, revision, scope);
40125
+ const loginOk = await client.login();
40126
+ if (revision !== sessionRevision || imSessionScope(messageStore) !== scope) {
40127
+ await disposeInstance(true);
40128
+ return false;
39882
40129
  }
39883
- imInstance == null ? void 0 : imInstance.initSDK();
39884
- bindMessageEvent();
39885
- const loginOk = await (imInstance == null ? void 0 : imInstance.login());
39886
40130
  if (loginOk !== false) httpAuthBroken = false;
39887
- window["imInstance"] = imInstance;
40131
+ if (typeof window !== "undefined") window.imInstance = client;
39888
40132
  return loginOk !== false;
39889
- })();
40133
+ });
40134
+ initPromise = operation;
39890
40135
  try {
39891
- return await initPromise;
40136
+ return await operation;
39892
40137
  } finally {
39893
- initPromise = null;
40138
+ if (initPromise === operation) {
40139
+ initPromise = null;
40140
+ pendingSessionKey = "";
40141
+ }
39894
40142
  }
39895
40143
  };
39896
- let reloginTimer = null;
39897
40144
  let reloginAttempts = 0;
39898
40145
  let tokenInvalidNotified = false;
39899
40146
  let recoveredToken = "";
@@ -39910,11 +40157,17 @@ const useMessage = (config = {}) => {
39910
40157
  notifyTokenInvalid({ errMsg: "auto relogin exhausted" });
39911
40158
  return;
39912
40159
  }
40160
+ const recoveryScope = imSessionScope(messageStore);
40161
+ const recoveryRevision = sessionRevision;
39913
40162
  reloginTimer = setTimeout(async () => {
39914
40163
  reloginTimer = null;
40164
+ if (recoveryRevision !== sessionRevision || recoveryScope !== imSessionScope(messageStore)) return;
39915
40165
  reloginAttempts += 1;
39916
40166
  console.warn(`[IM] token 已失效,自动重新登录(第 ${reloginAttempts} 次)`);
39917
40167
  const ok = await initIMSDK(true);
40168
+ const recoveryClient = imInstance;
40169
+ const currentRevision = sessionRevision;
40170
+ if (recoveryScope !== imSessionScope(messageStore) || !recoveryClient) return;
39918
40171
  if (!ok) {
39919
40172
  tryRelogin();
39920
40173
  return;
@@ -39923,7 +40176,9 @@ const useMessage = (config = {}) => {
39923
40176
  tokenInvalidNotified = false;
39924
40177
  try {
39925
40178
  await waitForSyncFinish(8e3);
39926
- const list = await (imInstance == null ? void 0 : imInstance.getConversationListSplit(0, 200));
40179
+ if (currentRevision !== sessionRevision || recoveryScope !== imSessionScope(messageStore)) return;
40180
+ const list = await recoveryClient.getConversationListSplit(0, 200);
40181
+ if (currentRevision !== sessionRevision || recoveryScope !== imSessionScope(messageStore)) return;
39927
40182
  if (list == null ? void 0 : list.length) {
39928
40183
  handleConversationList(list, "init", handleMessage);
39929
40184
  }
@@ -39957,34 +40212,31 @@ const useMessage = (config = {}) => {
39957
40212
  tokenInvalidNotified = false;
39958
40213
  tryRelogin();
39959
40214
  };
39960
- const clearInstance = async (bool) => {
39961
- unbindMessageEvent();
39962
- cancelAllBurns();
39963
- imInstance == null ? void 0 : imInstance.removeAllListeners();
39964
- await (imInstance == null ? void 0 : imInstance.logout());
39965
- imInstance == null ? void 0 : imInstance.clearSDK();
39966
- if (imInstance) {
39967
- imInstance.syncFinished = false;
39968
- }
39969
- resetSyncState();
39970
- if (bool) {
39971
- imInstance = null;
39972
- window.imInstance = null;
39973
- clearConversationList();
39974
- }
39975
- messageStore.setLoginStatus(IM_LOGIN_STATUS.Logout);
40215
+ const clearInstance = async () => {
40216
+ ++sessionRevision;
40217
+ pendingSessionKey = "";
40218
+ if (reloginTimer) clearTimeout(reloginTimer);
40219
+ reloginTimer = null;
40220
+ return enqueueSession(async () => {
40221
+ await disposeInstance(true);
40222
+ activeSessionScope = "";
40223
+ });
39976
40224
  };
39977
- const bindMessageEvent = () => {
39978
- if (!imInstance || !imInstance.on) return;
39979
- imInstance.on("im-error", handleImError);
40225
+ const bindMessageEvent = (client, revision, scope) => {
40226
+ const isActive = () => revision === sessionRevision && client === imInstance && imSessionScope(messageStore) === scope;
40227
+ const onSessionEvent = (event, handler) => client.on(event, (...args) => {
40228
+ if (isActive()) return handler(...args);
40229
+ });
40230
+ if (!client || !client.on) return;
40231
+ onSessionEvent("im-error", handleImError);
39980
40232
  bindUnhandledRejection(handleImError);
39981
- imInstance.on(CbEvents.OnUserTokenExpired, () => {
40233
+ onSessionEvent(CbEvents.OnUserTokenExpired, () => {
39982
40234
  console.log("用户授权信息过期,重新登录");
39983
40235
  });
39984
- imInstance.on(CbEvents.OnSelfInfoUpdated, (data) => {
40236
+ onSessionEvent(CbEvents.OnSelfInfoUpdated, (data) => {
39985
40237
  console.log("用户资料更新:", data);
39986
40238
  });
39987
- imInstance.on(CbEvents.OnUserStatusChanged, (data) => {
40239
+ onSessionEvent(CbEvents.OnUserStatusChanged, (data) => {
39988
40240
  console.log("用户在线状态变化:", data);
39989
40241
  if (data == null ? void 0 : data.userID) {
39990
40242
  updateUserStatus([data]);
@@ -40006,11 +40258,10 @@ const useMessage = (config = {}) => {
40006
40258
  }
40007
40259
  });
40008
40260
  const handleSunloginEvent = (data) => {
40009
- var _a;
40010
- const info = typeof data.data === "string" && data.data.indexOf("{") > -1 ? JSON.parse(data.data) : {};
40261
+ const info = parseIMBusinessData(data.data);
40262
+ if (!info) return;
40011
40263
  const { event, sendUserID, recvUserID, sendUserName, address, session } = info;
40012
- const currentUserId = (_a = messageStore.getUserInfo) == null ? void 0 : _a.userID;
40013
- if (sendUserID === currentUserId) return;
40264
+ if (!shouldHandleRemoteNotice(info, messageStore.getUserInfo)) return;
40014
40265
  const SUN_EVENTS = {
40015
40266
  "create-sl-remote": () => mittBus.emit("createSLRemote", { address, session }),
40016
40267
  "apply-sl-control": () => mittBus.emit("applySLControl", { sendUserName, sendUserID, recvUserID }),
@@ -40024,17 +40275,13 @@ const useMessage = (config = {}) => {
40024
40275
  if (handler) handler();
40025
40276
  };
40026
40277
  const handleImNoticeEvent = (data) => {
40027
- var _a, _b;
40028
- const info = typeof data.data === "string" && data.data.indexOf("{") > -1 ? JSON.parse(data.data) : {};
40029
- const { event, sendUserID, imToken } = info;
40030
- if (event !== "LOGIN_NOTICE") return;
40031
- const currentUserId = (_a = messageStore.getUserInfo) == null ? void 0 : _a.userID;
40032
- const curImToken = (_b = messageStore.getUserInfo) == null ? void 0 : _b.imToken;
40033
- if (sendUserID === currentUserId && imToken !== curImToken) {
40278
+ const info = parseIMBusinessData(data.data);
40279
+ if (!info) return;
40280
+ if (shouldHandleLoginNotice(info, messageStore.getUserInfo)) {
40034
40281
  mittBus.emit("LOGOUT_NOTICE");
40035
40282
  }
40036
40283
  };
40037
- imInstance.on(CbEvents.OnRecvCustomBusinessMessage, (data) => {
40284
+ onSessionEvent(CbEvents.OnRecvCustomBusinessMessage, (data) => {
40038
40285
  if (data.key === "sunlogin") {
40039
40286
  handleSunloginEvent(data);
40040
40287
  } else if (data.key === "imNotice") {
@@ -40044,13 +40291,14 @@ const useMessage = (config = {}) => {
40044
40291
  const resolveConversationIDs = async (list) => {
40045
40292
  var _a;
40046
40293
  for (let i3 = 0; i3 < list.length; i3++) {
40294
+ if (!isActive()) return;
40047
40295
  const item = list[i3];
40048
40296
  let cvsId = getConversationIDBySessionType(item, "sendID");
40049
40297
  if (!cvsId) {
40050
40298
  let info = null;
40051
40299
  if (!httpAuthBroken) {
40052
40300
  try {
40053
- info = await (imInstance == null ? void 0 : imInstance.getOneConversation(
40301
+ info = await (client == null ? void 0 : client.getOneConversation(
40054
40302
  item.sessionType === IM_CVS_TYPE.Single ? item.sendID : item.groupID,
40055
40303
  item == null ? void 0 : item.sessionType
40056
40304
  ));
@@ -40058,6 +40306,7 @@ const useMessage = (config = {}) => {
40058
40306
  console.warn("[IM] 获取会话信息失败,改用消息数据兜底:", error);
40059
40307
  }
40060
40308
  }
40309
+ if (!isActive()) return;
40061
40310
  if (info == null ? void 0 : info.conversationID) {
40062
40311
  item.showName = info.showName;
40063
40312
  item.faceURL = info.faceURL;
@@ -40066,7 +40315,8 @@ const useMessage = (config = {}) => {
40066
40315
  handleConversationList([info], "add", handleMessage);
40067
40316
  if (info.ex) {
40068
40317
  const clearedEx = preserveBurnInEx("", info.ex);
40069
- await (imInstance == null ? void 0 : imInstance.setConversation({ conversationID: cvsId, ex: clearedEx }));
40318
+ await (client == null ? void 0 : client.setConversation({ conversationID: cvsId, ex: clearedEx }));
40319
+ if (!isActive()) return;
40070
40320
  info.ex = clearedEx;
40071
40321
  }
40072
40322
  } else {
@@ -40101,6 +40351,7 @@ const useMessage = (config = {}) => {
40101
40351
  for (const [cvsID, items] of grouped) {
40102
40352
  try {
40103
40353
  const cached = ((_a = await loadMessagesFromCache(cvsID)) == null ? void 0 : _a.list) || [];
40354
+ if (!isActive()) return;
40104
40355
  saveMessagesToCache(cvsID, dedupeMessages([...cached, ...items]));
40105
40356
  } catch (error) {
40106
40357
  console.warn("[IM] 兜底会话消息写入缓存失败:", error);
@@ -40111,6 +40362,7 @@ const useMessage = (config = {}) => {
40111
40362
  const curMsgList = [];
40112
40363
  const cvs = currentConversation2.value;
40113
40364
  for (let i3 = 0; i3 < list.length; i3++) {
40365
+ if (!isActive()) return;
40114
40366
  const item = list[i3];
40115
40367
  const cvsId = item.conversationID;
40116
40368
  if (item.sessionType === IM_CVS_TYPE.Single && (cvs == null ? void 0 : cvs.userID) === item.sendID || item.groupID && cvs.groupID === item.groupID) {
@@ -40128,11 +40380,13 @@ const useMessage = (config = {}) => {
40128
40380
  }
40129
40381
  return curMsgList;
40130
40382
  };
40131
- imInstance.on(CbEvents.OnRecvNewMessages, async (list) => {
40383
+ onSessionEvent(CbEvents.OnRecvNewMessages, async (list) => {
40132
40384
  console.log("批量接收消息:", list);
40133
40385
  if ((list == null ? void 0 : list.length) > 0) {
40134
40386
  await resolveConversationIDs(list);
40387
+ if (!isActive()) return;
40135
40388
  await cacheFallbackMessages(list);
40389
+ if (!isActive()) return;
40136
40390
  const curMsgList = routeMessages(list);
40137
40391
  if (curMsgList.length > 0) {
40138
40392
  const cvs = currentConversation2.value;
@@ -40143,7 +40397,7 @@ const useMessage = (config = {}) => {
40143
40397
  }
40144
40398
  }
40145
40399
  });
40146
- imInstance.on(CbEvents.OnRecvC2CReadReceipt, async (list) => {
40400
+ onSessionEvent(CbEvents.OnRecvC2CReadReceipt, async (list) => {
40147
40401
  if ((list == null ? void 0 : list.length) > 0) {
40148
40402
  const cvs = currentConversation2.value;
40149
40403
  const curList = list.filter((item) => item.userID === (cvs == null ? void 0 : cvs.userID) && item.sessionType === IM_CVS_TYPE.Single);
@@ -40158,45 +40412,50 @@ const useMessage = (config = {}) => {
40158
40412
  setConversationMsgAsRead(cvs.conversationID);
40159
40413
  }
40160
40414
  });
40161
- imInstance.on(CbEvents.OnNewRecvMessageRevoked, (data) => {
40415
+ onSessionEvent(CbEvents.OnNewRecvMessageRevoked, (data) => {
40162
40416
  if (data == null ? void 0 : data.clientMsgID) {
40163
40417
  revokeMessage(data);
40164
40418
  }
40165
40419
  });
40166
- imInstance.on("updateStatus", (val = 1) => {
40420
+ onSessionEvent("updateStatus", (val = 1) => {
40167
40421
  console.log("登录状态", val);
40168
40422
  messageStore.setLoginStatus(val);
40169
40423
  if (val === IM_LOGIN_STATUS.Logged) {
40170
- setTimeout(() => {
40424
+ initTimer = setTimeout(() => {
40425
+ if (!isActive()) return;
40171
40426
  getUnReadMessageCount();
40172
40427
  }, 1e3);
40173
40428
  } else if (val === IM_LOGIN_STATUS.Logout) {
40174
40429
  mittBus.emit("IM_LOGOUT");
40175
40430
  }
40176
40431
  });
40177
- imInstance.on(CbEvents.OnSyncServerStart, () => {
40432
+ onSessionEvent(CbEvents.OnSyncServerStart, () => {
40178
40433
  console.log("IM 服务端同步开始");
40179
40434
  syncFinished = false;
40180
40435
  });
40181
- imInstance.on(CbEvents.OnSyncServerFinish, () => {
40436
+ onSessionEvent(CbEvents.OnSyncServerFinish, () => {
40182
40437
  console.log("IM 服务端同步完成");
40183
40438
  resolveSyncWaiters(true);
40184
40439
  mittBus.emit("IM_SYNC_SERVER_FINISH", true);
40185
40440
  });
40186
- imInstance.on(CbEvents.OnSyncServerFailed, (data) => {
40441
+ onSessionEvent(CbEvents.OnSyncServerFailed, (data) => {
40187
40442
  console.warn("IM 服务端同步失败:", data);
40188
40443
  resolveSyncWaiters(false);
40189
40444
  mittBus.emit("IM_SYNC_SERVER_FINISH", false);
40190
40445
  });
40191
- imInstance.on("im-error", async (err) => {
40446
+ onSessionEvent("im-error", async (err) => {
40447
+ if (initTimer) {
40448
+ clearTimeout(initTimer);
40449
+ initTimer = null;
40450
+ }
40192
40451
  });
40193
- imInstance.on(CbEvents.OnConversationChanged, (data) => {
40452
+ onSessionEvent(CbEvents.OnConversationChanged, (data) => {
40194
40453
  if (Array.isArray(data) && (data == null ? void 0 : data.length)) {
40195
40454
  console.log("会话状态改变:", data);
40196
40455
  handleConversationList(data, "update", handleMessage);
40197
40456
  }
40198
40457
  });
40199
- imInstance.on(CbEvents.OnNewConversation, async (data) => {
40458
+ onSessionEvent(CbEvents.OnNewConversation, async (data) => {
40200
40459
  console.log("新会话:", data);
40201
40460
  if (data == null ? void 0 : data.length) {
40202
40461
  const cvsIds = conversationList2.value.map((item) => item.conversationID);
@@ -40204,7 +40463,8 @@ const useMessage = (config = {}) => {
40204
40463
  const userIds = newList.filter((item) => item.conversationType === IM_CVS_TYPE.Single).map((item) => item.userID);
40205
40464
  let statusInfo = {};
40206
40465
  if (userIds.length > 0) {
40207
- const statusList = await (imInstance == null ? void 0 : imInstance.subscribeUsersStatus(userIds));
40466
+ const statusList = await (client == null ? void 0 : client.subscribeUsersStatus(userIds));
40467
+ if (!isActive()) return;
40208
40468
  statusInfo = updateUserStatus(statusList);
40209
40469
  }
40210
40470
  newList.forEach((item) => {
@@ -40220,48 +40480,48 @@ const useMessage = (config = {}) => {
40220
40480
  mittBus.emit("OnNewConversationCreated", data);
40221
40481
  }
40222
40482
  });
40223
- imInstance.on(CbEvents.OnGroupInfoChanged, (data) => {
40483
+ onSessionEvent(CbEvents.OnGroupInfoChanged, (data) => {
40224
40484
  if (data == null ? void 0 : data.groupID) {
40225
40485
  mittBus.emit("OnGroupInfoChanged", data);
40226
40486
  }
40227
40487
  });
40228
- imInstance.on(CbEvents.OnGroupMemberInfoChanged, (data) => {
40488
+ onSessionEvent(CbEvents.OnGroupMemberInfoChanged, (data) => {
40229
40489
  if (data == null ? void 0 : data.groupID) {
40230
40490
  updateMessageSenderInfo(data);
40231
40491
  mittBus.emit("OnGroupMemberInfoChanged", data);
40232
40492
  }
40233
40493
  });
40234
- imInstance.on(CbEvents.OnJoinedGroupAdded, (data) => {
40494
+ onSessionEvent(CbEvents.OnJoinedGroupAdded, (data) => {
40235
40495
  if (data == null ? void 0 : data.groupID) {
40236
40496
  mittBus.emit("OnJoinedGroupAdded", data.groupID);
40237
40497
  }
40238
40498
  });
40239
- imInstance.on(CbEvents.OnGroupMemberAdded, (data) => {
40499
+ onSessionEvent(CbEvents.OnGroupMemberAdded, (data) => {
40240
40500
  if (data == null ? void 0 : data.groupID) {
40241
40501
  mittBus.emit("OnGroupMemberAdded", data);
40242
40502
  }
40243
40503
  });
40244
- imInstance.on(CbEvents.OnGroupApplicationAdded, (data) => {
40504
+ onSessionEvent(CbEvents.OnGroupApplicationAdded, (data) => {
40245
40505
  console.log("收到入群申请通知:", data);
40246
40506
  mittBus.emit("OnGroupApplicationAdded", data);
40247
40507
  });
40248
- imInstance.on(CbEvents.OnGroupApplicationAccepted, (data) => {
40508
+ onSessionEvent(CbEvents.OnGroupApplicationAccepted, (data) => {
40249
40509
  console.log("入群申请被同意:", data);
40250
40510
  mittBus.emit("OnGroupApplicationAccepted", data);
40251
40511
  });
40252
- imInstance.on(CbEvents.OnGroupApplicationRejected, (data) => {
40512
+ onSessionEvent(CbEvents.OnGroupApplicationRejected, (data) => {
40253
40513
  console.log("入群申请被拒绝:", data);
40254
40514
  mittBus.emit("OnGroupApplicationRejected", data);
40255
40515
  });
40256
- imInstance.on(CbEvents.OnJoinedGroupDeleted, (data) => {
40516
+ onSessionEvent(CbEvents.OnJoinedGroupDeleted, (data) => {
40257
40517
  if (data.groupID) {
40258
40518
  mittBus.emit("OnJoinedGroupDeleted", data.groupID);
40259
40519
  }
40260
40520
  });
40261
- imInstance.on(CbEvents.OnGroupMemberDeleted, (data) => {
40521
+ onSessionEvent(CbEvents.OnGroupMemberDeleted, (data) => {
40262
40522
  mittBus.emit("OnGroupMemberDeleted", data);
40263
40523
  });
40264
- imInstance.on(CbEvents.OnGroupDismissed, (data) => {
40524
+ onSessionEvent(CbEvents.OnGroupDismissed, (data) => {
40265
40525
  if (data && data.groupID) {
40266
40526
  data.status = IM_GROUP_STATUS.Dismissed;
40267
40527
  mittBus.emit("OnGroupInfoChanged", data);
@@ -40296,6 +40556,24 @@ const useMessage = (config = {}) => {
40296
40556
  imInstance.off(CbEvents.OnGroupApplicationAccepted);
40297
40557
  imInstance.off(CbEvents.OnGroupApplicationRejected);
40298
40558
  };
40559
+ if (!subscribedStores.has(messageStore)) {
40560
+ subscribedStores.add(messageStore);
40561
+ let previousScope = imSessionScope(messageStore);
40562
+ messageStore.$subscribe((_mutation, state) => {
40563
+ let nextScope = "";
40564
+ try {
40565
+ nextScope = imSessionScope(state);
40566
+ } catch {
40567
+ }
40568
+ if (previousScope === nextScope) return;
40569
+ previousScope = nextScope;
40570
+ clearConversationList();
40571
+ clearMessageList();
40572
+ resetUsers();
40573
+ cancelAllBurns();
40574
+ void clearInstance().catch((error) => console.error("[IM] 会话切换清理失败:", error));
40575
+ }, { detached: true, flush: "sync" });
40576
+ }
40299
40577
  return {
40300
40578
  messageStore,
40301
40579
  loginStatus,
@@ -40308,63 +40586,65 @@ const useMessage = (config = {}) => {
40308
40586
  };
40309
40587
  };
40310
40588
  export {
40311
- getDefaultExportFromCjs as $,
40312
- isBurnMessage as A,
40589
+ uuidv4 as $,
40590
+ getReplyDetail as A,
40313
40591
  BURN_DEFAULT as B,
40314
- formatBurnRemain as C,
40315
- isBurned as D,
40316
- EXIT_CODE as E,
40317
- smoothScrollTo as F,
40318
- getJsonDetail as G,
40319
- getSelectionText as H,
40320
- IM_CVS_TYPE as I,
40321
- useBurnAfterReading as J,
40322
- createCvsId as K,
40323
- dedupeMessages as L,
40324
- handleUrl as M,
40325
- handleDate as N,
40326
- GROUP_JOIN_SOURCE as O,
40327
- GROUP_APPLICATION_STATUS as P,
40328
- useMessage as Q,
40329
- useUsers as R,
40330
- useConversations as S,
40331
- useMessageCache as T,
40332
- mittBus as U,
40333
- IM_LOGIN_STATUS as V,
40334
- preserveBurnInEx as W,
40335
- buildBurnEx as X,
40336
- sleep as Y,
40337
- uuidv4 as Z,
40338
- GROUP_VERIFICATION_TYPE as _,
40339
- getAvatarBg as a,
40340
- getMediaDuration as a0,
40341
- IM_FONT_SIZE as a1,
40342
- IM_FONT_FAMILY as a2,
40343
- IM_FONT_STYLE as a3,
40344
- formatFileSize as a4,
40345
- getAvatarText as b,
40346
- cloneDeep as c,
40347
- getConversationBurnSetting as d,
40348
- useDate as e,
40349
- isNoticeAgentConversation as f,
40592
+ useMsgList as C,
40593
+ throttle as D,
40594
+ isBurnMessage as E,
40595
+ formatBurnRemain as F,
40596
+ isBurned as G,
40597
+ smoothScrollTo as H,
40598
+ IMSessionChangedError as I,
40599
+ getJsonDetail as J,
40600
+ getSelectionText as K,
40601
+ useBurnAfterReading as L,
40602
+ createCvsId as M,
40603
+ dedupeMessages as N,
40604
+ handleUrl as O,
40605
+ handleDate as P,
40606
+ GROUP_JOIN_SOURCE as Q,
40607
+ GROUP_APPLICATION_STATUS as R,
40608
+ useMessage as S,
40609
+ useUsers as T,
40610
+ useConversations as U,
40611
+ useMessageCache as V,
40612
+ mittBus as W,
40613
+ IM_LOGIN_STATUS as X,
40614
+ preserveBurnInEx as Y,
40615
+ buildBurnEx as Z,
40616
+ sleep as _,
40617
+ IM_CVS_TYPE as a,
40618
+ GROUP_VERIFICATION_TYPE as a0,
40619
+ getDefaultExportFromCjs as a1,
40620
+ getMediaDuration as a2,
40621
+ IM_FONT_SIZE as a3,
40622
+ IM_FONT_FAMILY as a4,
40623
+ IM_FONT_STYLE as a5,
40624
+ formatFileSize as a6,
40625
+ isDefaultAvatar as b,
40626
+ getAvatarBg as c,
40627
+ getAvatarText as d,
40628
+ cloneDeep as e,
40629
+ getConversationBurnSetting as f,
40350
40630
  getGroupAvatarBg as g,
40351
- IM_GROUP_MEMBER_ROLE as h,
40352
- isDefaultAvatar as i,
40353
- IM_MSG_TYPE as j,
40354
- debounce as k,
40355
- IM_GROUP_STATUS as l,
40356
- IM_LOGIN_PLATFORM as m,
40357
- BURN_PRESETS as n,
40358
- formatBurnDuration as o,
40359
- BURN_MAX as p,
40360
- BURN_MIN as q,
40361
- handleLinks as r,
40362
- clampBurnDuration as s,
40363
- copyToClipboard as t,
40631
+ useDate as h,
40632
+ imSessionScope as i,
40633
+ isNoticeAgentConversation as j,
40634
+ IM_GROUP_MEMBER_ROLE as k,
40635
+ IM_MSG_TYPE as l,
40636
+ debounce as m,
40637
+ IM_GROUP_STATUS as n,
40638
+ IM_LOGIN_PLATFORM as o,
40639
+ BURN_PRESETS as p,
40640
+ formatBurnDuration as q,
40641
+ requestInstance as r,
40642
+ BURN_MAX as s,
40643
+ BURN_MIN as t,
40364
40644
  useChatStore as u,
40365
- downloadFileByBlob as v,
40366
- formatSeconds as w,
40367
- getReplyDetail as x,
40368
- useMsgList as y,
40369
- throttle as z
40645
+ handleLinks as v,
40646
+ clampBurnDuration as w,
40647
+ copyToClipboard as x,
40648
+ downloadFileByBlob as y,
40649
+ formatSeconds as z
40370
40650
  };