You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
apply-assistant-v3/App.vue

519 lines
14 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script lang="ts">
import RootStore from "@xkit-yx/im-store-v2";
import V2NIM, { V2NIMConst } from "nim-web-sdk-ng/dist/v2/NIM_UNIAPP_SDK";
import { getMsgContentTipByType } from "./pages/NEUIKit/utils/msg";
import { STORAGE_KEY } from "./pages/NEUIKit/utils/constants";
import { isWxApp } from "./pages/NEUIKit/utils";
import { V2NIMMessage, V2NIMMessagePushConfig, V2NIMConversation } from "nim-web-sdk-ng/dist/v2/NIM_UNIAPP_SDK/V2NIMMessageService";
import { unix } from "dayjs";
export default {
globalData: {
timer: null, // 定时器变量
reconnectTimer: null, // 重连专用定时器
themeColor: "#00b666",
themeBackgroundColor: "#00b66621",
},
onLaunch() {
let that = this;
uni.removeStorageSync("selectedCity");
// 监听路由跳转
uni.addInterceptor("navigateTo", {
invoke(args) {
console.log("navigateTo 跳转前", args);
that.G.watchUserPage(args.url);
},
});
uni.addInterceptor("reLaunch", {
invoke(args) {
console.log("reLaunch 跳转前", args);
that.G.watchUserPage(args.url);
},
});
uni.addInterceptor("redirectTo", {
invoke(args) {
console.log("redirectTo 跳转前", args);
that.G.watchUserPage(args.url);
},
});
},
onShow: function (options) {
let that = this;
console.log("show 项目init", options, decodeURIComponent(options.query.scene));
// 清除扫码获取的id信息
uni.removeStorageSync("scene");
uni.removeStorageSync("user_scene");
uni.removeStorageSync("user_options", options);
if (options.query.id) {
uni.setStorageSync("apply-jobdetail-id", options.query.id);
} else {
uni.setStorageSync("apply-jobdetail-id", 0);
}
if (options.query.scene) {
let str = decodeURIComponent(options.query.scene);
uni.setStorageSync(
"apply-invite-code",
JSON.stringify({
key: str.split("=")[0],
value: str.split("=")[1],
})
);
} else {
uni.setStorageSync("apply-invite-code", "");
}
if (uni.getStorageSync("apply-token")) {
this.G.checkToken();
}
// 初始化定时器 - 合并检查任务
if (!that.globalData.timer) {
that.checkNum();
that.checkAndReconnectIM(); // 立即检查一次连接
// 缩短检查间隔到15秒兼顾消息提醒和连接检查
that.globalData.timer = setInterval(() => {
that.checkNum();
that.checkAndReconnectIM();
}, 15 * 1000);
}
uni.$on("isGlogin", function (data) {
console.log("app.vue 接收", data);
if (uni.getStorageSync("apply-uid")) {
that.initWyyx();
}
});
// 应用从后台返回时检查连接
if (uni.getStorageSync("apply-token")) {
console.log("app.vue 检查IM连接状态");
that.checkAndReconnectIM();
}
},
onHide: function () {
// 应用进入后台时不清除定时器,保持心跳
console.log("应用进入后台保持IM连接检测");
// 发送一次心跳包
if (uni.$UIKitNIM && uni.$UIKitNIM.V2NIMLoginService) {
uni.$UIKitNIM.V2NIMLoginService.ping().then(() => {
console.log("后台心跳发送成功");
}).catch(err => {
console.error("后台心跳发送失败,准备重连", err);
this.reconnectIM();
});
}
},
onUnload() {
// 页面卸载时才清除定时器
if (this.globalData.timer) {
clearInterval(this.globalData.timer);
this.globalData.timer = null;
console.log("定时器已清除");
}
if (this.globalData.reconnectTimer) {
clearInterval(this.globalData.reconnectTimer);
this.globalData.reconnectTimer = null;
}
},
methods: {
// 检查并重新连接IM
checkAndReconnectIM() {
let that = this;
// 延迟执行确保SDK初始化完成
setTimeout(() => {
if (uni.$UIKitNIM && uni.$UIKitStore) {
const connectStatus = uni.$UIKitStore.connectStore.connectStatus;
console.log('当前IM连接状态:', connectStatus);
// 连接状态码:
// 0: 初始状态
// 1: 已断开
// 2: 已连接
// 3: 连接中
if (connectStatus !== 2 && connectStatus !== 3) {
console.log("IM连接已断开尝试重连...");
that.reconnectIM();
}
} else if (uni.getStorageSync("apply-token") && uni.getStorageSync("apply-uid")) {
console.log("IM SDK未初始化重新初始化...");
that.initWyyx();
}
}, 1000);
},
// 重新连接IM
reconnectIM() {
let that = this;
// 如果已经在重连中,则不再重复发起
if (this.globalData.reconnectTimer) {
console.log("正在重连中,无需重复操作");
return;
}
// 尝试重连
const attemptReconnect = () => {
if (!uni.getStorageSync("apply-token") || !uni.getStorageSync("apply-uid")) {
console.log("用户未登录,停止重连");
clearInterval(that.globalData.reconnectTimer);
that.globalData.reconnectTimer = null;
return;
}
if (uni.$UIKitNIM && uni.$UIKitNIM.V2NIMLoginService) {
const account = uni.getStorageSync("im-accid");
const token = uni.getStorageSync("im-token");
if (account && token) {
console.log(`尝试重连IM (account: ${account})`);
uni.$UIKitNIM.V2NIMLoginService.login(account, token)
.then(() => {
console.log("IM重连成功");
clearInterval(that.globalData.reconnectTimer);
that.globalData.reconnectTimer = null;
})
.catch((error) => {
console.error("IM重连失败将再次尝试", error);
});
} else {
console.log("重连信息不全重新初始化IM");
that.initWyyx();
}
} else {
console.log("SDK未初始化重新初始化IM");
that.initWyyx();
}
};
// 立即尝试一次重连
// attemptReconnect();
// 设置重连定时器每5秒尝试一次最多尝试10次
let reconnectAttempts = 0;
this.globalData.reconnectTimer = setInterval(() => {
reconnectAttempts++;
if (reconnectAttempts >= 10) {
console.log("重连尝试次数已达上限,停止重连");
clearInterval(that.globalData.reconnectTimer);
that.globalData.reconnectTimer = null;
return;
}
attemptReconnect();
}, 5000);
},
initWyyx() {
let that = this;
that.F.wyyxPost(
that.api.wyyx_getConfig,
{
userId: uni.getStorageSync("apply-uid"),
},
(res) => {
console.log("wyyx_getConfig", res);
// 检查返回数据有效性
if (!res || !res.appKey || !res.accid || !res.token) {
console.error("获取IM配置失败参数不完整");
return;
}
let resData = {
appkey: res.appKey,
accid: res.accid,
token: res.token,
};
// 保存IM配置信息用于重连
uni.setStorageSync('im-appkey', resData.appkey);
uni.setStorageSync('im-accid', resData.accid);
uni.setStorageSync('im-token', resData.token);
const imOptions = {
appkey: resData.appkey,
account: resData.accid,
token: resData.token,
};
this.initNim(imOptions);
}
);
},
async initNim(opts) {
let that = this;
// 初始化 nim sdk增强重连配置
const nim = (uni.$UIKitNIM = V2NIM.getInstance(
{
appkey: opts.appkey,
needReconnect: true,
reconnectionAttempts: 10, // 增加重连次数
reconnectionDelay: 3000, // 重连间隔3秒
heartbeatInterval: 20000, // 缩短心跳间隔为20秒
debugLevel: "warn", // 提高日志级别便于调试
apiVersion: "v2",
enableV2CloudConversation: true,
},
{
V2NIMLoginServiceConfig: {
lbsUrls: isWxApp ? ["https://lbs.netease.im/lbs/wxwebconf.jsp"] : ["https://lbs.netease.im/lbs/webconf.jsp"],
linkUrl: isWxApp ? "wlnimsc0.netease.im" : "weblink.netease.im",
isFixedDeviceId: true, // 使用固定设备ID
autoLogin: true, // 允许自动登录
},
}
));
that.globalData.nim = nim;
// 初始化 store
const store = (uni.$UIKitStore = new RootStore(
nim,
{
addFriendNeedVerify: false,
p2pMsgReceiptVisible: true,
teamMsgReceiptVisible: true,
teamAgreeMode: V2NIMConst.V2NIMTeamAgreeMode.V2NIM_TEAM_AGREE_MODE_NO_AUTH,
sendMsgBefore: async (options: { msg: V2NIMMessage; conversationId: string; serverExtension?: Record<string, unknown> }) => {
const pushContent = getMsgContentTipByType({
text: options.msg.text,
messageType: options.msg.messageType,
});
const yxAitMsg = options.serverExtension ? options.serverExtension.yxAitMsg : { forcePushIDsList: "[]", needForcePush: false };
const { forcePushIDsList, needForcePush } = yxAitMsg
? // @ts-ignore
store.msgStore._formatExtAitToPushInfo(yxAitMsg, options.msg.text)
: { forcePushIDsList: "[]", needForcePush: false };
console.log("forcePushIDsList: ", forcePushIDsList);
const { conversationId } = options;
const conversationType = nim.V2NIMConversationIdUtil.parseConversationType(conversationId);
const targetId = nim.V2NIMConversationIdUtil.parseConversationTargetId(conversationId);
const pushPayload = JSON.stringify({
oppoField: {
click_action_type: 4,
click_action_activity: "",
action_parameters: {
sessionId: targetId,
sessionType: conversationType,
},
},
vivoField: {
pushMode: 0,
},
hwField: {
click_action: {
type: 1,
action: "",
},
androidConfig: {
category: "IM",
data: JSON.stringify({
sessionId: targetId,
sessionType: conversationType,
}),
},
},
sessionId: targetId,
sessionType: conversationType,
});
const pushConfig: V2NIMMessagePushConfig = {
pushEnabled: true,
pushNickEnabled: true,
forcePush: needForcePush,
forcePushContent: pushContent,
forcePushAccountIds: forcePushIDsList,
pushPayload: "{}",
pushContent,
};
return { ...options, pushConfig };
},
},
"UniApp"
));
// 监听连接状态变化
nim.V2NIMLoginService.on("onConnectStatusChanged", (status) => {
console.log("IM连接状态变化:", status);
// 状态1表示已断开连接
if (status === 1) {
console.log("检测到连接断开,触发重连");
that.reconnectIM();
}
});
// #ifdef APP-PLUS
const nimPushPlugin = uni.requireNativePlugin("NIMUniPlugin-PluginModule");
nim.V2NIMSettingService.setOfflinePushConfig(nimPushPlugin, {
miPush: {
appId: "2882303761520397320",
appKey: "5102039734320",
certificateName: "xiaomiCertificateName",
},
vivoPush: {
certificateName: "vivoCertificateName",
},
oppoPush: {
appId: "32967155",
appKey: "b98618cb272944dea324af6421d42a79",
secret: "0b7ce705a2304a17b78f20011c18890c",
certificateName: "opopCertificateName",
},
honorPush: {
certificateName: "rongyaoCertificateName",
},
apns: {
certificateName: "AuthKey_98P8URRXUD",
},
});
console.log("推送配置已设置");
// #endif
// 登录IM
nim.V2NIMLoginService.login(opts.account, opts.token)
.then(() => {
console.log("IM登录成功");
// 清除重连定时器
if (that.globalData.reconnectTimer) {
clearInterval(that.globalData.reconnectTimer);
that.globalData.reconnectTimer = null;
}
})
.catch((error) => {
console.error("IM登录失败", error);
// 登录失败时启动重连机制
that.reconnectIM();
});
// 监听会话变化
nim.V2NIMConversationService.on("onConversationChanged", function (conversationList: V2NIMConversation[]) {
console.log("初始化监听会话:", conversationList);
let unreadConversations = conversationList.filter((item) => {
return Number(item.unreadCount) > 0;
});
console.log("未读会话数量:", unreadConversations.length);
if (unreadConversations.length > 0) {
that.playAudio();
}
});
},
playAudio() {
let that = this;
const innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.autoplay = true;
innerAudioContext.src = "https://matripe-cms.oss-cn-beijing.aliyuncs.com/ibocai/tip.mp3";
innerAudioContext.onPlay(() => {
console.log("开始播放提示音");
});
uni.vibrateShort();
innerAudioContext.onError((res) => {
console.log("提示音播放错误:", res.errMsg, res.errCode);
});
},
checkNum() {
let that = this;
if (uni.getStorageSync("apply-token")) {
that.G.Get(that.api.bind_getApplyNum, {}, (res) => {
console.log("获取待处理数量:", res);
that.G.Get(that.api.person_applyNum, {}, (applyNum) => {
if (res.approvePassHasNotRed + applyNum > 0) {
uni.setTabBarBadge({
index: 2,
text: String(res.approvePassHasNotRed + applyNum),
fail(err) {
console.log("设置tabBar徽章失败:", err);
},
});
} else {
uni.removeTabBarBadge({
index: 2,
fail(err) {
console.log("移除tabBar徽章失败:", err);
},
});
}
});
});
}
},
},
};
</script>
<style lang="scss">
@import "./static/css/iconfont.css";
@import "./uni_modules/vk-uview-ui/index.scss";
@import "./static/css/base.scss";
// #ifdef MP-WEIXIN
page {
width: 100vw;
height: 100vh;
}
// #endif
// #ifdef H5 || APP-PLUS || MP-TOUTIAO || MP-KUAISHOU
page {
width: 100vw;
height: calc(100% - 0px);
--color-ysd: #ff4400;
--color-hover: #ff4400cc;
--color-be: #ff4400;
--color-027: #ff4400;
--color-href: #576b95;
}
// #endif
// uview默认样式覆盖
.u-badge-mini {
top: 22rpx !important;
right: 102rpx !important;
color: transparent !important;
width: 10px !important;
height: 10px !important;
border-radius: 50% !important;
}
.u-radio {
&:last-child {
.u-radio__label {
margin-right: 0;
}
}
}
.g-apply-tab {
.u-tab-bar {
bottom: -2px !important;
}
}
.g_bg_f_5 {
background-color: #ededed !important;
}
.g_mt_30 {
margin-top: 30px;
}
.g_mt_84 {
margin-top: 84px;
}
.g_pt_90 {
padding-top: 90px;
}
</style>