/** * 应用入口 */ const envConfig = require('./env.config.js'); const storage = require('./utils/storage.js'); const { gateway } = require('./services/gateway.js'); const { mqttClient } = require('./services/mqtt-client.js'); App({ globalData: { // 用户信息 userInfo: null, userId: null, token: null, // 环境配置 envConfig: envConfig, // 当前连接的设备 currentDevice: null, // MQTT 客户端 mqttClient: null, }, onLaunch() { console.log('[App] onLaunch'); // 检查登录态 this.checkLoginStatus(); this._listenNetwork(); }, /** * 监听网络状态:恢复联网后立刻补连 * * 工业现场网络抖动是常态。只靠 socket 事件被动等恢复,弱网/飞行模式切回来 * 可能需要等一个 keepalive 周期才有反应;主动监听能立刻把链路拉起来。 */ _listenNetwork() { if (this._networkListening) return; this._networkListening = true; wx.onNetworkStatusChange((res) => { console.log('[App] 网络状态变化:', res.networkType, 'isConnected:', res.isConnected); if (!res.isConnected) return; if (!this.isLoggedIn()) return; // 网关内部幂等:已连接/正在自愈时会自行短路,不会重复建连 gateway.resume(); }); }, // 回到前台:让网关补起连接/重连/补传离线 onShow() { console.log('[App] onShow'); if (this.isLoggedIn()) { gateway.resume(); } }, // 切后台:记录时间并暂停网关主动重试(不 teardown) onHide() { console.log('[App] onHide'); gateway.suspend(); }, /** * 检查登录状态 * 登录态只依赖 userId(登录一次即可,业务流程不使用 token) */ checkLoginStatus() { const userInfo = storage.getUserInfo(); if (userInfo && userInfo.userId) { this.globalData.userInfo = userInfo; this.globalData.userId = userInfo.userId; // token 可选保存(仅登录流程使用,业务不依赖) this.globalData.token = storage.getToken() || null; console.log('[App] 已登录, userId:', userInfo.userId); } else { console.log('[App] 未登录'); } }, /** * 设置登录信息 * @param {Object} data - 登录返回数据 { token, user } */ setLoginInfo(data) { const userInfo = { userId: data.userId, userName: data.userName, phonenumber: data.phonenumber, avatar: data.avatar, }; this.globalData.token = data.token; this.globalData.userInfo = userInfo; this.globalData.userId = data.userId; // 持久化存储 storage.setToken(data.token); storage.setUserInfo(userInfo); // 重新登录后清除"用户主动断开"意图:新会话应恢复自动连接 // (否则上一次退出登录时置的标记会让 MQTT 永远连不上) mqttClient.allowAutoConnect(); console.log('[App] 登录成功, userId:', data.userId); }, /** * 清除登录信息(退出登录唯一出口) * * 退出登录必须清干净:BLE 采集停掉、MQTT 断开、本地业务数据(设备列表 / * MQTT 产品凭证 / 离线缓存 / 命令 / 测点上下文)一并清除, * 否则换人登录会看到上一位用户的设备与凭证。 */ async clearLoginInfo() { // 网关只持有 BLE,MQTT 由「我的」页建立,两处都要显式拆 await gateway.stop(); await mqttClient.disconnect(); this.globalData.token = null; this.globalData.userInfo = null; this.globalData.userId = null; this.globalData.currentDevice = null; storage.clearAll(); console.log('[App] 已退出登录'); }, /** * 检查是否已登录 * 只检查 userId,token 过期不影响登录态(登录一次即可) * @returns {boolean} */ isLoggedIn() { return !!this.globalData.userId; }, });