import cron from 'node-cron' import { prisma } from './db.js' import mysql from 'mysql2/promise' import { fetchNewsList, persistNews } from '../scripts/fetchers/news.fetcher.js' import { checkAfterRefresh } from './alert-engine.js' import { ApizeroError, oil, history } from './apizero/index.js' function parseUrl(url) { const u = new URL(url) return { host: u.hostname, port: Number(u.port) || 3306, user: decodeURIComponent(u.username), password: decodeURIComponent(u.password), database: u.pathname.replace(/^\//, '') } } async function openConn() { return mysql.createConnection(parseUrl(process.env.DATABASE_URL)) } // 每天凌晨 3:00 (本地时间) 拉取新闻 + 跑跨源对比 function scheduleNews() { cron.schedule('0 3 * * *', async () => { console.log('[cron] 3:00 触发') try { const list = await fetchNewsList() const r = await persistNews(list) console.log('[cron] 新闻入库: 新增 ' + r.inserted + ' / 跳过 ' + r.skipped) const conn = await openConn() try { const a = await checkAfterRefresh(conn) console.log('[cron] 报警检测: 新增 ' + a.inserted + ' 条 (扫描 ' + a.scanned + ')') } finally { await conn.end() } } catch (e) { console.error('[cron] 任务失败:', e.message) } }) console.log('[cron] 已注册: 每天 03:00 拉取新闻 + 跨源报警检测') } // 每天凌晨 4:00 抓浙江油价历史 // 逻辑: 拉今年 schedule, 检查待定且 <= 昨天的调价日, 命中就抓 price?province=浙江 存库 // - 0 命中: 不调 apizero (省配额) // - >0 命中: 调一次, 4 个油品批量入库 (unique 兜底去重) function scheduleOilHistory() { cron.schedule('0 4 * * *', async () => { console.log('[cron] 4:00 油价历史触发') try { const year = new Date().getFullYear() const sched = await oil.getSchedule(year) const list = sched.schedule || [] // 待定 且 日期 <= 昨天 const today = new Date() today.setHours(0, 0, 0, 0) const yesterdayMs = today.getTime() - 86400000 const pendingPast = list.filter((it) => { if (it.status !== '待定') return false const t = new Date(it.date + 'T00:00:00').getTime() return Number.isFinite(t) && t <= yesterdayMs }) console.log('[cron] 待定且已过的调价日: ' + pendingPast.length + ' 个') if (pendingPast.length === 0) { console.log('[cron] 油价历史: 0 命中, 跳过 apizero 调用') return } const r = await history.fetchAndStore() console.log('[cron] 油价历史入库: 新增 ' + r.inserted + ' / 跳过 ' + r.skipped + ' (date=' + r.date + ')') } catch (e) { if (e instanceof ApizeroError) { console.error('[cron] 油价历史 apizero 错误: code=' + e.code + ' msg=' + e.message) } else { console.error('[cron] 油价历史任务失败:', e.message) } } }) console.log('[cron] 已注册: 每天 04:00 浙江油价历史抓取') } scheduleNews() scheduleOilHistory()