抽出日期计算纯函数模块,并搭建后端测试基建
- 新增 server/src/occurrence.js:startOfDay/getNextOccurrence/daysBetween,today 可注入 - reminder.js 改为调用新模块,删除内联的 getThisYearDate/daysBetween - 引入 node:test 作为测试框架,加 npm test 脚本 - 新增 test/helper.js(临时库辅助,供后续任务用)和 test/occurrence.test.js(7 个用例,覆盖农历跨年等边界)
This commit is contained in:
+3
-36
@@ -2,6 +2,7 @@ const cron = require('node-cron')
|
||||
const db = require('./db')
|
||||
const wx = require('./wx')
|
||||
const lunar = require('./lunar')
|
||||
const occurrence = require('./occurrence')
|
||||
|
||||
const TEMPLATE_ID = process.env.WX_TEMPLATE_ID
|
||||
const MINIPROGRAM_STATE = process.env.WX_MINIPROGRAM_STATE || 'formal'
|
||||
@@ -27,40 +28,6 @@ function formatDate(date) {
|
||||
return `${y}年${m}月${d}日`
|
||||
}
|
||||
|
||||
// 算出"距离今年(或明年)这个纪念日还有多少天"
|
||||
// 农历纪念日按 lunarMonth/lunarDay 计算每年对应的公历日期,否则按 solarMonth/solarDay
|
||||
function getThisYearDate(anniv) {
|
||||
const today = new Date()
|
||||
today.setHours(0, 0, 0, 0)
|
||||
|
||||
if (anniv.isLunar && anniv.lunarMonth && anniv.lunarDay) {
|
||||
// 闰月生日按 A 方案处理:若当年无对应闰月,lunarToSolar 内部已自动按普通月份算
|
||||
const todayLunar = lunar.solarToLunar(today)
|
||||
const wantLeap = !!anniv.isLeapMonth
|
||||
let target = lunar.lunarToSolar(todayLunar.year, anniv.lunarMonth, anniv.lunarDay, wantLeap)
|
||||
target.setHours(0, 0, 0, 0)
|
||||
if (target < today) {
|
||||
target = lunar.lunarToSolar(todayLunar.year + 1, anniv.lunarMonth, anniv.lunarDay, wantLeap)
|
||||
target.setHours(0, 0, 0, 0)
|
||||
}
|
||||
return target
|
||||
}
|
||||
|
||||
let target = new Date(today.getFullYear(), anniv.solarMonth - 1, anniv.solarDay)
|
||||
target.setHours(0, 0, 0, 0)
|
||||
if (target < today) {
|
||||
target = new Date(today.getFullYear() + 1, anniv.solarMonth - 1, anniv.solarDay)
|
||||
target.setHours(0, 0, 0, 0)
|
||||
}
|
||||
return target
|
||||
}
|
||||
|
||||
function daysBetween(target) {
|
||||
const today = new Date()
|
||||
today.setHours(0, 0, 0, 0)
|
||||
return Math.round((target - today) / 86400000)
|
||||
}
|
||||
|
||||
// 检查今天是否已经给这条纪念日发过提醒
|
||||
function alreadySentToday(anniversaryId) {
|
||||
const start = new Date()
|
||||
@@ -87,8 +54,8 @@ async function runOnce() {
|
||||
|
||||
for (const anniv of list) {
|
||||
try {
|
||||
const target = getThisYearDate(anniv)
|
||||
const daysUntil = daysBetween(target)
|
||||
const target = occurrence.getNextOccurrence(anniv)
|
||||
const daysUntil = occurrence.daysBetween(target)
|
||||
|
||||
const shouldRemind = (daysUntil === 0) || (daysUntil === (anniv.remindDays || 0))
|
||||
if (!shouldRemind) continue
|
||||
|
||||
Reference in New Issue
Block a user