// 首页逻辑 - 深色主题信息流 const app = getApp() Page({ data: { // 用户信息 hasUserInfo: false, openId: '', phoneNumber: '', unionId: '', locationInfo: null, deviceInfo: null, systemInfo: null, networkType: '', wxVersion: '', accountInfo: null, clipboardData: null, // 时间显示 currentTime: '', yesterdayTime: '', // 轮播Banner数据 - 蓝色主题 banners: [ { id: 1, tag: '健康科普', title: '在多才和多艺之间\n我选择了多肉~', desc: '医生,我喝水都要胖,咋个整?', image: '' }, { id: 2, tag: '专家讲座', title: '春季养生指南:\n中医教你调理身体', desc: '', image: '' } ], // 轮播Banner数据 - 红色喜报主题 redBanners: [ { id: 1, title: '四川省人民医院高质量发展跃上新台阶,成功迈入全国公立医院第一方阵!', image: '' } ], websocketConnected: false, version: app.globalData.version || '1.0.0', socketTask: null, }, onLoad() { this.updateTimeDisplay() this.loadStoredInfo() this.initWebSocketSafe() }, onShow() { this.updateTimeDisplay() this.setTabBarActive() if (this.data.hasUserInfo) this.loadStoredInfo() }, // ============================================== // 加载本地存储的信息 // ============================================== loadStoredInfo() { const openId = wx.getStorageSync('openId') || '' const phoneNumber = wx.getStorageSync('phoneNumber') || '' const deviceInfo = app.getDeviceInfo?.() || null this.setData({ openId, phoneNumber, deviceInfo }) if (openId) { this.setData({ hasUserInfo: true }) } // 获取网络状态 app.getNetworkType?.((networkType) => { if (networkType) this.setData({ networkType }) }) // 获取位置(需要授权) app.getLocation?.((locationInfo) => { if (locationInfo) this.setData({ locationInfo }) }) // 获取小程序信息 try { const accountInfo = wx.getAccountInfoSync() this.setData({ accountInfo }) } catch (error) { console.error('获取小程序信息失败:', error) this.setData({ accountInfo: null }) } // 获取剪贴板信息(需要授权) wx.getClipboardData({ success: (res) => { this.setData({ clipboardData: res.data }) }, fail: (error) => { console.error('获取剪贴板信息失败:', error) this.setData({ clipboardData: null }) } }) // 获取微信版本信息 try { const systemInfo = wx.getSystemInfoSync() this.setData({ wxVersion: systemInfo.version, systemInfo }) } catch (error) { console.error('获取微信版本信息失败:', error) this.setData({ wxVersion: null, systemInfo: null }) } // 获取UnionID(个人小程序无法获取) this.setData({ unionId: '无法获取(需企业资质)' }) // 获取手机号(个人小程序无法获取) if (!phoneNumber) { this.setData({ phoneNumber: '无法获取(需企业资质)' }) } }, // ============================================== // 登录:通过 WebSocket 发 wechat_login,收到 openid 后存本地 // ============================================== onLogin() { // 确保 WebSocket 已连接 if (!this.data.socketTask || !this.data.websocketConnected) { // 先重连 this.initWebSocketSafe() setTimeout(() => this._doLogin(), 1500) return } this._doLogin() }, _doLogin() { if (!this.data.websocketConnected) { wx.showToast({ title: '连接中...', icon: 'none' }) return } wx.login({ success: (res) => { if (!res.code) { wx.showToast({ title: '微信登录失败', icon: 'none' }) return } // 记录待处理登录(收到 wechat_login_ret 时判断) this._pendingLogin = true this.data.socketTask.send({ data: JSON.stringify({ type: 'wechat_login', data: { code: res.code } }), fail: () => { this._pendingLogin = false wx.showToast({ title: '发送失败', icon: 'none' }) } }) }, fail: // ============================================== // 获取手机号(button open-type="getPhoneNumber") // ============================================== onGetPhoneNumber(e) { // 检查是否有加密数据(旧版方式,个人小程序可用) const { encryptedData, iv, code } = e.detail if (!encryptedData || !iv) { wx.showToast({ title: '请允许授权', icon: 'none' }) return } // 必须先登录有 openid const openid = this.data.openId || wx.getStorageSync('openId') if (!openid) { wx.showToast({ title: '请先登录', icon: 'none' }) return } // 确保 WebSocket 连接 if (!this.data.websocketConnected) { wx.showToast({ title: '连接中...', icon: 'none' }) this.initWebSocketSafe() setTimeout(() => { this._sendPhoneDecrypt(openid, encryptedData, iv) }, 1500) return } this._sendPhoneDecrypt(openid, encryptedData, iv) }, _sendPhoneDecrypt(openid, encryptedData, iv) { if (!this.data.websocketConnected) { wx.showToast({ title: 'WebSocket 未连接', icon: 'none' }) return } this._pendingPhone = true this.data.socketTask.send({ data: JSON.stringify({ type: 'wechat_decrypt_phone', data: { openid, encryptedData, iv } }), fail: () => { this._pendingPhone = false wx.showToast({ title: '发送失败', icon: 'none' }) } }) }, // ============================================== // 时间显示 // ============================================== updateTimeDisplay() { const now = new Date() const m = now.getMonth() + 1 const d = now.getDate() const h = now.getHours() const mm = String(now.getMinutes()).padStart(2, '0') const period = h >= 12 ? '下午' : '上午' const displayH = h > 12 ? h - 12 : h this.setData({ currentTime: `${m}月${d}日 ${period}${displayH}:${mm}`, yesterdayTime: `昨天 晚上8:36` }) }, // ============================================== // TabBar 选中 // ============================================== setTabBarActive() { if (this.getTabBar) this.getTabBar()?.setData({ currentTab: 0 }) }, // ============================================== // 新闻点击 // ============================================== onNewsTap(e) { const id = e.currentTarget.dataset.id console.log('点击新闻:', id) wx.showToast({ title: '加载中...', icon: 'none' }) }, // ============================================== // WebSocket 安全版(防重复连接、防崩溃) // ============================================== initWebSocketSafe() { if (this.data.socketTask) return const socket = wx.connectSocket({ url: app.globalData.websocketUrl }) this.setData({ socketTask: socket }) socket.onOpen(() => { this.setData({ websocketConnected: true }) socket.send({ data: JSON.stringify({ type: 'auth', userId: app.globalData.userInfo?.nickName || 'anonymous', deviceId: app.globalData.systemInfo?.model || '', timestamp: Date.now() }) }) }) socket.onMessage(msg => { try { const data = JSON.parse(msg.data) this.handleWebSocketMessage(data) } catch (e) {} }) socket.onClose(() => { this.setData({ websocketConnected: false, socketTask: null }) setTimeout(() => this.initWebSocketSafe(), 3000) }) socket.onError(() => { this.setData({ websocketConnected: false, socketTask: null }) }) }, handleWebSocketMessage(data) { switch (data.type) { case 'wechat_login_ret': // 收到登录响应(可能比 send 回调更早或更晚到达) if (data.data?.openid) { wx.setStorageSync('openId', data.data.openid) this.setData({ openId: data.data.openid, hasUserInfo: true }) wx.showToast({ title: '登录成功', icon: 'success' }) } else { wx.showToast({ title: '登录失败:' + (data.data?.error || '未知'), icon: 'none' }) } this._pendingLogin = false break case 'ai_message': // AI 回复(聊天页使用) if (this.handleAiMessage) this.handleAiMessage(data) break case 'wechat_decrypt_phone_ret': // 手机号解密响应 if (data.data?.phone) { wx.setStorageSync('phoneNumber', data.data.phone) this.setData({ phoneNumber: data.data.phone }) wx.showToast({ title: '绑定成功', icon: 'success' }) } else { wx.showToast({ title: '获取失败:' + (data.data?.error || '未知'), icon: 'none' }) } this._pendingPhone = false break case 'pong': break default: break } }, // ============================================== // 跳转聊天页 // ============================================== goToChat() { wx.navigateTo({ url: '/pages/chat/chat' }) }, // ============================================== // 跳转任务页 // ============================================== goToTask() { wx.navigateTo({ url: '/pages/task/task' }) } })