// 云函数:发送生日提醒 const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() // 模板ID const TEMPLATE_ID = '6J7Stt-lu7DKU6jblJ0nZGq_D81z5glnksf7qWfy5Yw' /** * 计算两个日期之间的天数差 */ function getDaysUntil(targetDate) { const today = new Date() today.setHours(0, 0, 0, 0) const target = new Date(targetDate) target.setHours(0, 0, 0, 0) const diffTime = target - today const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) return diffDays } /** * 格式化日期 */ function formatDate(date) { const d = new Date(date) const year = d.getFullYear() const month = String(d.getMonth() + 1).padStart(2, '0') const day = String(d.getDate()).padStart(2, '0') return `${year}年${month}月${day}日` } const TYPE_NAMES = { birthday: '公历生日', lunar_birthday: '农历生日', wedding: '结婚纪念日', engagement: '订婚纪念日', other: '其他纪念日' } /** * 获取类型名称 */ function getTypeName(type, customName) { if (type === 'other' && customName) return customName return TYPE_NAMES[type] || '纪念日' } /** * 获取今年的纪念日日期 */ function getThisYearDate(anniversary) { const today = new Date() const currentYear = today.getFullYear() // 使用公历日期计算 let thisYearDate = new Date(currentYear, anniversary.solarMonth - 1, anniversary.solarDay) // 如果今年的已经过了,计算明年的 const daysUntil = getDaysUntil(thisYearDate) if (daysUntil < 0) { thisYearDate = new Date(currentYear + 1, anniversary.solarMonth - 1, anniversary.solarDay) } return thisYearDate } /** * 主函数 */ exports.main = async (event, context) => { console.log('开始执行提醒任务...') try { // 获取所有启用提醒的纪念日 const anniversariesRes = await db.collection('anniversaries') .where({ remindEnabled: true }) .get() console.log(`找到 ${anniversariesRes.data.length} 条启用提醒的纪念日`) let successCount = 0 let failCount = 0 // 遍历每个纪念日 for (const anniversary of anniversariesRes.data) { try { // 计算今年的纪念日日期 const thisYearDate = getThisYearDate(anniversary) const daysUntil = getDaysUntil(thisYearDate) console.log(`${anniversary.personName} 的 ${getTypeName(anniversary.type, anniversary.customTypeName)},还有 ${daysUntil} 天`) // 判断是否需要提醒 const shouldRemind = ( daysUntil === 0 || // 当天 daysUntil === anniversary.remindDays // 提前N天 ) if (shouldRemind) { // 检查今天是否已经发送过提醒 const today = new Date() today.setHours(0, 0, 0, 0) const logRes = await db.collection('remind_logs') .where({ anniversaryId: anniversary._id, sendDate: db.command.gte(today) }) .count() if (logRes.total > 0) { console.log(`今天已发送过提醒,跳过: ${anniversary.personName}`) continue } // 发送订阅消息 const sendRes = await cloud.openapi.subscribeMessage.send({ touser: anniversary.openid, page: 'pages/index/index', data: { name1: { value: anniversary.personName }, thing2: { value: daysUntil === 0 ? '今天' : `还有${daysUntil}天` }, thing6: { value: formatDate(thisYearDate) }, thing5: { value: anniversary.remark || '别忘了准备一份礼物哦!' } }, templateId: TEMPLATE_ID, miniprogramState: 'formal' // 正式版 }) console.log(`发送成功: ${anniversary.personName}`, sendRes) // 记录提醒日志 await db.collection('remind_logs').add({ data: { anniversaryId: anniversary._id, personName: anniversary.personName, typeName: getTypeName(anniversary.type, anniversary.customTypeName), daysUntil: daysUntil, sendDate: new Date(), status: 'success' } }) successCount++ } } catch (err) { console.error(`发送失败: ${anniversary.personName}`, err) failCount++ // 记录失败日志 await db.collection('remind_logs').add({ data: { anniversaryId: anniversary._id, personName: anniversary.personName, sendDate: new Date(), status: 'failed', error: err.message } }) } } console.log(`提醒任务完成: 成功${successCount}条,失败${failCount}条`) return { success: true, total: anniversariesRes.data.length, successCount, failCount } } catch (err) { console.error('提醒任务执行失败:', err) return { success: false, error: err.message } } }