const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() const _ = db.command function timeText(ts) { if (!ts) return '' const d = new Date(ts) const hh = String(d.getHours()).padStart(2, '0') const mm = String(d.getMinutes()).padStart(2, '0') const sameDay = new Date().toDateString() === d.toDateString() if (sameDay) return `${hh}:${mm}` return `${d.getMonth() + 1}/${d.getDate()} ${hh}:${mm}` } async function userToPeer(u) { return { id: u._id, name: u.nickname || '用户', avatarKey: u.avatarKey || 'gradient-avatar-1', avatarUrl: u.avatarUrl || '' } } exports.main = async event => { const { OPENID } = cloud.getWXContext() if (!OPENID) throw new Error('no openid in wx context') let convId = event.conversationId || '' let peer = null // Open by target user — resolve peer and find an existing conversation. if (!convId && event.targetUserId) { const tRes = await db.collection('users').doc(event.targetUserId).get().catch(() => null) const t = tRes && tRes.data if (t) { peer = await userToPeer(t) const ex = await db.collection('conversations') .where({ type: 'single', memberOpenids: _.all([OPENID, t.openid]) }) .limit(1) .get() .catch(() => ({ data: [] })) if (ex.data.length) convId = ex.data[0]._id } } // Open by conversation — resolve the other member as peer. if (convId && !peer) { const c = await db.collection('conversations').doc(convId).get().catch(() => null) if (c && c.data) { const otherOpenid = (c.data.memberOpenids || []).find(o => o !== OPENID) if (otherOpenid) { const oRes = await db.collection('users').where({ openid: otherOpenid }).limit(1).get() if (oRes.data[0]) peer = await userToPeer(oRes.data[0]) } if (!peer) { peer = { id: '', name: c.data.title || '对话', avatarKey: c.data.avatarKey || 'gradient-avatar-1', avatarUrl: '' } } } } let messages = [] if (convId) { const res = await db.collection('messages') .where({ conversationId: convId }) .orderBy('createdAt', 'desc') .limit(50) .get() .catch(() => ({ data: [] })) messages = res.data.reverse().map(m => ({ _id: m._id, fromMe: m.fromOpenid === OPENID, content: m.content, type: m.type || 'text', createdAt: m.createdAt, timeText: timeText(m.createdAt) })) // Mark this conversation read for me. await db.collection('conversations').doc(convId).update({ data: { unreadOpenids: _.pull(OPENID), [`unreadCounts.${OPENID}`]: 0 } }).catch(() => {}) } return { conversationId: convId, peer, messages } }