Files
im-uniapp/App.vue
2025-07-07 14:53:19 +08:00

544 lines
18 KiB
Vue
Raw 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.

<script>
import { mapGetters, mapActions } from "vuex";
import IMSDK, {
IMMethods,
MessageType,
SessionType,
} from "openim-uniapp-polyfill";
import config from "./common/config";
import { getDbDir, toastWithCallback } from "@/util/common.js";
import { conversationSort } from "@/util/imCommon";
import { PageEvents, UpdateMessageTypes } from "@/constant";
const openSdk = uni.requireNativePlugin('Tuoyun-OpenIMSDK');
const globalEvent = uni.requireNativePlugin('globalEvent');
export default {
onLaunch: function () {
console.log("App Launch");
console.log(openSdk);
this.setGlobalIMlistener();
this.tryLogin();
// #ifdef APP-PLUS
checkUpdate(); // 直接调用独立函数避免this问题
// #endif
// #ifdef H5
console.error(
`暂时不支持运行到 Web如果需要移动端的 Web 项目,参考 [H5 demo](https://github.com/openimsdk/openim-h5-demo)`
);
// #endif
// #ifdef MP-WEIXIN
console.error(`暂时不支持运行到小程序端`);
// #endif
},
onShow: function () {
console.log("App Show");
IMSDK.asyncApi(IMSDK.IMMethods.SetAppBackgroundStatus, IMSDK.uuid(), false);
},
onHide: function () {
console.log("App Hide");
IMSDK.asyncApi(IMSDK.IMMethods.SetAppBackgroundStatus, IMSDK.uuid(), true);
},
computed: {
...mapGetters([
"storeConversationList",
"storeCurrentConversation",
"storeCurrentUserID",
"storeSelfInfo",
"storeRecvFriendApplications",
"storeRecvGroupApplications",
"storeHistoryMessageList",
"storeIsSyncing",
"storeGroupList",
]),
},
methods: {
...mapActions("message", ["pushNewMessage", "updateOneMessage"]),
...mapActions("conversation", ["updateCurrentMemberInGroup"]),
...mapActions("contact", [
"updateFriendInfo",
"pushNewFriend",
"updateBlackInfo",
"pushNewBlack",
"pushNewGroup",
"updateGroupInfo",
"pushNewRecvFriendApplition",
"updateRecvFriendApplition",
"pushNewSentFriendApplition",
"updateSentFriendApplition",
"pushNewRecvGroupApplition",
"updateRecvGroupApplition",
"pushNewSentGroupApplition",
"updateSentGroupApplition",
]),
setGlobalIMlistener() {
console.log("setGlobalIMlistener");
// init
const kickHander = (message) => {
toastWithCallback(message, () => {
uni.removeStorage({
key: "IMToken",
});
uni.removeStorage({
key: "BusinessToken",
});
uni.$u.route("/pages/login/index");
});
};
IMSDK.subscribe(IMSDK.IMEvents.OnKickedOffline, (data) => {
kickHander("您的账号在其他设备登录,请重新登陆!");
});
IMSDK.subscribe(IMSDK.IMEvents.OnUserTokenExpired, (data) => {
kickHander("您的登录已过期,请重新登陆!");
});
IMSDK.subscribe(IMSDK.IMEvents.OnUserTokenInvalid, (data) => {
kickHander("您的登录已无效,请重新登陆!");
});
// sync
const syncStartHandler = ({ data }) => {
this.$store.commit("user/SET_IS_SYNCING", true);
this.$store.commit("user/SET_REINSTALL", data);
};
const syncProgressHandler = ({ data }) => {
this.$store.commit("user/SET_PROGRESS", data);
};
const syncFinishHandler = () => {
uni.hideLoading();
this.$store.dispatch("conversation/getConversationList");
this.$store.dispatch("contact/getFriendList");
this.$store.dispatch("contact/getGrouplist");
this.$store.dispatch("conversation/getUnReadCount");
this.$store.commit("user/SET_IS_SYNCING", false);
};
const syncFailedHandler = () => {
uni.hideLoading();
uni.$u.toast("同步消息失败");
this.$store.dispatch("conversation/getConversationList");
this.$store.dispatch("conversation/getUnReadCount");
this.$store.commit("user/SET_IS_SYNCING", false);
};
IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerStart, syncStartHandler);
IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerFinish, syncFinishHandler);
IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerFailed, syncFailedHandler);
IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerProgress, syncProgressHandler);
// self
const selfInfoUpdateHandler = ({ data }) => {
this.$store.commit("user/SET_SELF_INFO", {
...this.storeSelfInfo,
...data,
});
};
IMSDK.subscribe(IMSDK.IMEvents.OnSelfInfoUpdated, selfInfoUpdateHandler);
// message
const newMessagesHandler = ({ data }) => {
if (this.storeIsSyncing) {
return;
}
data.forEach(this.handleNewMessage);
};
IMSDK.subscribe(IMSDK.IMEvents.OnRecvNewMessages, newMessagesHandler);
// friend
const friendInfoChangeHandler = ({ data }) => {
uni.$emit(IMSDK.IMEvents.OnFriendInfoChanged, { data });
this.updateFriendInfo({
friendInfo: data,
});
};
const friendAddedHandler = ({ data }) => {
this.pushNewFriend(data);
};
const friendDeletedHander = ({ data }) => {
this.updateFriendInfo({
friendInfo: data,
isRemove: true,
});
};
IMSDK.subscribe(
IMSDK.IMEvents.OnFriendInfoChanged,
friendInfoChangeHandler
);
IMSDK.subscribe(IMSDK.IMEvents.OnFriendAdded, friendAddedHandler);
IMSDK.subscribe(IMSDK.IMEvents.OnFriendDeleted, friendDeletedHander);
// blacklist
const blackAddedHandler = ({ data }) => {
this.pushNewBlack(data);
};
const blackDeletedHandler = ({ data }) => {
this.updateBlackInfo({
blackInfo: data,
isRemove: true,
});
};
IMSDK.subscribe(IMSDK.IMEvents.OnBlackAdded, blackAddedHandler);
IMSDK.subscribe(IMSDK.IMEvents.OnBlackDeleted, blackDeletedHandler);
// group
const joinedGroupAddedHandler = ({ data }) => {
this.pushNewGroup(data);
};
const joinedGroupDeletedHandler = ({ data }) => {
this.updateGroupInfo({
groupInfo: data,
isRemove: true,
});
};
const groupInfoChangedHandler = ({ data }) => {
this.updateGroupInfo({
groupInfo: data,
});
};
const groupMemberInfoChangedHandler = ({ data }) => {
uni.$emit(IMSDK.IMEvents.OnGroupMemberInfoChanged, { data });
if (data.groupID === this.storeCurrentConversation?.groupID) {
this.updateCurrentMemberInGroup(data);
}
};
IMSDK.subscribe(
IMSDK.IMEvents.OnJoinedGroupAdded,
joinedGroupAddedHandler
);
IMSDK.subscribe(
IMSDK.IMEvents.OnJoinedGroupDeleted,
joinedGroupDeletedHandler
);
IMSDK.subscribe(
IMSDK.IMEvents.OnGroupInfoChanged,
groupInfoChangedHandler
);
IMSDK.subscribe(
IMSDK.IMEvents.OnGroupMemberInfoChanged,
groupMemberInfoChangedHandler
);
// application
const friendApplicationNumHandler = ({ data }) => {
const isRecv = data.toUserID === this.storeCurrentUserID;
if (isRecv) {
this.pushNewRecvFriendApplition(data);
} else {
this.pushNewSentFriendApplition(data);
}
};
const friendApplicationAccessHandler = ({ data }) => {
const isRecv = data.toUserID === this.storeCurrentUserID;
if (isRecv) {
this.updateRecvFriendApplition({
application: data,
});
} else {
this.updateSentFriendApplition({
application: data,
});
}
};
const groupApplicationNumHandler = ({ data }) => {
const isRecv = data.userID !== this.storeCurrentUserID;
if (isRecv) {
this.pushNewRecvGroupApplition(data);
} else {
this.pushNewSentGroupApplition(data);
}
};
const groupApplicationAccessHandler = ({ data }) => {
const isRecv = data.userID !== this.storeCurrentUserID;
if (isRecv) {
this.updateRecvGroupApplition({
application: data,
});
} else {
this.updateSentGroupApplition({
application: data,
});
}
};
IMSDK.subscribe(
IMSDK.IMEvents.OnFriendApplicationAdded,
friendApplicationNumHandler
);
IMSDK.subscribe(
IMSDK.IMEvents.OnFriendApplicationAccepted,
friendApplicationAccessHandler
);
IMSDK.subscribe(
IMSDK.IMEvents.OnFriendApplicationRejected,
friendApplicationAccessHandler
);
IMSDK.subscribe(
IMSDK.IMEvents.OnGroupApplicationAdded,
groupApplicationNumHandler
);
IMSDK.subscribe(
IMSDK.IMEvents.OnGroupApplicationAccepted,
groupApplicationAccessHandler
);
IMSDK.subscribe(
IMSDK.IMEvents.OnGroupApplicationRejected,
groupApplicationAccessHandler
);
// conversation
const totalUnreadCountChangedHandler = ({ data }) => {
if (this.storeIsSyncing) {
return;
}
this.$store.commit("conversation/SET_UNREAD_COUNT", data);
};
const newConversationHandler = ({ data }) => {
if (this.storeIsSyncing) {
return;
}
const result = [...data, ...this.storeConversationList];
this.$store.commit(
"conversation/SET_CONVERSATION_LIST",
conversationSort(result)
);
};
const conversationChangedHandler = ({ data }) => {
if (this.storeIsSyncing) {
return;
}
let filterArr = [];
console.log(data);
const chids = data.map((ch) => ch.conversationID);
filterArr = this.storeConversationList.filter(
(tc) => !chids.includes(tc.conversationID)
);
const idx = data.findIndex(
(c) =>
c.conversationID === this.storeCurrentConversation.conversationID
);
if (idx !== -1)
this.$store.commit(
"conversation/SET_CURRENT_CONVERSATION",
data[idx]
);
const result = [...data, ...filterArr];
this.$store.commit(
"conversation/SET_CONVERSATION_LIST",
conversationSort(result)
);
};
IMSDK.subscribe(
IMSDK.IMEvents.OnTotalUnreadMessageCountChanged,
totalUnreadCountChangedHandler
);
IMSDK.subscribe(IMSDK.IMEvents.OnNewConversation, newConversationHandler);
IMSDK.subscribe(
IMSDK.IMEvents.OnConversationChanged,
conversationChangedHandler
);
},
tryLogin() {
const initStore = () => {
this.$store.dispatch("user/getSelfInfo");
this.$store.dispatch("conversation/getConversationList");
this.$store.dispatch("conversation/getUnReadCount");
this.$store.dispatch("contact/getFriendList");
this.$store.dispatch("contact/getGrouplist");
this.$store.dispatch("contact/getBlacklist");
this.$store.dispatch("contact/getRecvFriendApplications");
this.$store.dispatch("contact/getSentFriendApplications");
this.$store.dispatch("contact/getRecvGroupApplications");
this.$store.dispatch("contact/getSentGroupApplications");
uni.switchTab({
url: "/pages/conversation/conversationList/index?isRedirect=true",
});
};
getDbDir()
.then(async (path) => {
const flag = await IMSDK.asyncApi(IMMethods.InitSDK, IMSDK.uuid(), {
systemType: "uni-app",
apiAddr: config.getApiUrl(), // SDK的API接口地址。如http://xxx:10002
wsAddr: config.getWsUrl(), // SDK的websocket地址。如 ws://xxx:10001
dataDir: path, // 数据存储路径
logLevel: 6,
logFilePath: path,
isLogStandardOutput: true,
isExternalExtensions: false,
});
if (!flag) {
plus.navigator.closeSplashscreen();
uni.$u.toast("初始化IMSDK失败");
return;
}
const status = await IMSDK.asyncApi(
IMSDK.IMMethods.GetLoginStatus,
IMSDK.uuid()
);
if (status === 3) {
initStore();
return;
}
const IMToken = uni.getStorageSync("IMToken");
const IMUserID = uni.getStorageSync("IMUserID");
if (IMToken && IMUserID) {
IMSDK.asyncApi(IMSDK.IMMethods.Login, IMSDK.uuid(), {
userID: IMUserID,
token: IMToken,
})
.then(initStore)
.catch((err) => {
console.log(err);
uni.removeStorage({
key: "IMToken",
});
uni.removeStorage({
key: "BusinessToken",
});
plus.navigator.closeSplashscreen();
});
} else {
plus.navigator.closeSplashscreen();
}
})
},
handleNewMessage(newServerMsg) {
if (this.inCurrentConversation(newServerMsg)) {
if (
newServerMsg.contentType !== MessageType.TypingMessage &&
newServerMsg.contentType !== MessageType.RevokeMessage
) {
newServerMsg.isAppend = true;
this.pushNewMessage(newServerMsg);
setTimeout(() => uni.$emit(PageEvents.ScrollToBottom, true));
uni.$u.debounce(this.markConversationAsRead, 2000);
}
}
},
inCurrentConversation(newServerMsg) {
switch (newServerMsg.sessionType) {
case SessionType.Single:
return (
newServerMsg.sendID === this.storeCurrentConversation.userID ||
(newServerMsg.sendID === this.storeCurrentUserID &&
newServerMsg.recvID === this.storeCurrentConversation.userID)
);
case SessionType.WorkingGroup:
return newServerMsg.groupID === this.storeCurrentConversation.groupID;
case SessionType.Notification:
return newServerMsg.sendID === this.storeCurrentConversation.userID;
default:
return false;
}
},
markConversationAsRead() {
IMSDK.asyncApi(
IMSDK.IMMethods.MarkConversationMessageAsRead,
IMSDK.uuid(),
this.storeCurrentConversation.conversationID
);
},
},
};
function checkUpdate() {
const localVersion = plus.runtime.version;
const localWgtVersion = uni.getStorageSync('wgtVersion') || localVersion;
uni.request({
url: 'http://47.117.71.33:11295/fadapp-update/version.json?t=' + Date.now(),
success: (res) => {
const remoteVersion = res.data.version;
const wgtUrl = res.data.wgtUrl;
// 取本地基座和本地wgt的最大版本
const currentVersion = compareVersion(localWgtVersion, localVersion) > 0 ? localWgtVersion : localVersion;
console.log('本地基座版本:', localVersion, '本地wgt版本:', localWgtVersion, '当前对比版本:', currentVersion, '远程版本:', remoteVersion);
if (compareVersion(remoteVersion, currentVersion) > 0) {
uni.showModal({
title: '发现新版本',
content: `检测到新版本(${remoteVersion}),是否立即下载并更新?`,
confirmText: '立即更新',
cancelText: '暂不更新',
success: (modalRes) => {
if (modalRes.confirm) {
uni.showLoading({title: '正在下载更新包...'});
uni.downloadFile({
url: wgtUrl,
success: (downloadResult) => {
uni.hideLoading();
if (downloadResult.statusCode === 200) {
plus.runtime.install(downloadResult.tempFilePath, {force: true}, function() {
// 更新本地wgt版本号
uni.setStorageSync('wgtVersion', remoteVersion);
uni.showModal({
title: '更新完成',
content: '应用需要重启才能生效,是否立即重启?',
success: function (res) {
if (res.confirm) {
plus.runtime.restart();
}
}
});
}, function(e) {
uni.showToast({title: '安装失败: ' + e.message});
});
} else {
uni.showToast({title: '下载失败'});
}
},
fail: () => {
uni.hideLoading();
uni.showToast({title: '下载失败'});
}
});
}
}
});
} else {
uni.showToast({title: '当前已是最新版本'});
}
},
fail: () => {
uni.showToast({title: '检查更新失败'});
}
});
}
function extractVersionNum(str) {
const match = str.match(/(\\d+\\.\\d+(?:\\.\\d+)?)/);
return match ? match[1] : '0.0.0';
}
function compareVersion(v1, v2) {
v1 = extractVersionNum(v1).split('.').map(Number);
v2 = extractVersionNum(v2).split('.').map(Number);
for (let i = 0; i < Math.max(v1.length, v2.length); i++) {
const n1 = v1[i] || 0;
const n2 = v2[i] || 0;
if (n1 > n2) return 1;
if (n1 < n2) return -1;
}
return 0;
}
</script>
<style lang="scss">
/*每个页面公共css */
@import "@/uni_modules/uview-ui/index.scss";
@import "@/styles/login.scss";
@import "@/styles/global.scss";
uni-page-body {
height: 100vh;
overflow: hidden;
}
.uni-tabbar .uni-tabbar__icon {
width: 28px !important;
height: 28px !important;
}
</style>