import { api } from '../../utils/api' import { AppGlobalData } from '../../types/index' const app = getApp<{ globalData: AppGlobalData }>() Page({ data: { statusBarHeight: 0, peerId: '', peerName: '', messages: [] as any[], inputText: '', scrollToMsg: '', }, _watcher: null as any, onLoad(query: { userId?: string }) { const info = wx.getSystemInfoSync() this.setData({ statusBarHeight: info.statusBarHeight, peerId: query.userId || '' }) this.loadPeerInfo() this.loadMessages() this.subscribeRealtime() }, onUnload() { this._watcher?.close() }, async loadPeerInfo() { if (!this.data.peerId) return try { const user = await api.getUserProfile(this.data.peerId) this.setData({ peerName: user.nickName || '宠物爱好者' }) } catch {} }, async loadMessages() { if (!this.data.peerId) return try { const res = await api.getMessages(this.data.peerId) const msgs = res.list.map((m: any) => ({ ...m, isMe: m.fromId === app.globalData?.userInfo?._id, })) this.setData({ messages: msgs }) this.scrollToBottom() } catch {} }, subscribeRealtime() { const db = wx.cloud.database() this._watcher = db.collection('messages') .where({ toId: app.globalData?.userInfo?._id }) .watch({ onChange: snapshot => { if (snapshot.type === 'add') { const newMsgs = snapshot.docs.map((d: any) => ({ ...d, isMe: false })) this.setData({ messages: [...this.data.messages, ...newMsgs] }) this.scrollToBottom() } }, onError: () => {}, }) }, scrollToBottom() { const msgs = this.data.messages if (msgs.length > 0) { this.setData({ scrollToMsg: `msg-${msgs[msgs.length - 1]._id}` }) } }, onInput(e: WechatMiniprogram.CustomEvent) { this.setData({ inputText: e.detail.value }) }, async onSend() { const text = this.data.inputText.trim() if (!text) return this.setData({ inputText: '' }) const tempMsg = { _id: `temp_${Date.now()}`, content: text, isMe: true, fromId: app.globalData?.userInfo?._id, toId: this.data.peerId, } this.setData({ messages: [...this.data.messages, tempMsg] }) this.scrollToBottom() try { await api.sendMessage(this.data.peerId, text) } catch { wx.showToast({ title: '发送失败', icon: 'none' }) } }, onBack() { wx.navigateBack() }, })