// 延迟任务管理器 timerMap 存储的数据库表 order-trigger-task const { getDatabase, connectToMongoDB } = require("../../mongodb"); let timerMap = new Map(); module.exports = async (item, mongodb) => { db = mongodb; switch (item.type) { case "createDelayedTask": return await createDelayedTask(item); case "deleteDelayedTask": return await deleteDelayedTask(item); case "recoverDelayedTasks": return await recoverDelayedTasks(); } }; async function createDelayedTask({ triggerTaskId, endTime, corpId }) { createSetTimeOut({ triggerTaskId, endTime, corpId }); const db = await getDatabase("Internet-hospital"); await db.collection("order-trigger-task").insertOne({ triggerTaskId, endTime, corpId, }); } // 执行延迟任务 async function createSetTimeOut({ triggerTaskId, endTime, corpId }) { // 1. 计算延迟时间 let delayTime = endTime - Date.now(); if (delayTime <= 0) delayTime = 0; const timer = setTimeout(async () => { triggerDelayedTask({ triggerTaskId, corpId }); deleteDelayedTask({ triggerTaskId }); }, delayTime); // 4. 保存延迟任务 timerMap.set(triggerTaskId, timer); } // 触发延迟任务 async function triggerDelayedTask({ triggerTaskId }) { const db = await getDatabase("Internet-hospital"); const order = await db .collection("consult-order") .findOne({ orderId: triggerTaskId }); if (!order) return { success: false, message: "订单不存在", }; if (order.orderStatus !== "cancelled" || order.orderStatus !== "finished") { const consultOrder = require("./index"); const { orderStatus, orderSource } = order; let reason = `本次问诊已取消,取消原因:${ orderStatus === "pending" ? "超时未接诊" : "超时未处理" }。${ orderSource === "MATEPAD" ? "请联系线下退费。" : "费用将于48小时内退还您的支付账户。" }`; await consultOrder( { type: "refundFeeAndOrder", orderId: triggerTaskId, reason, }, db ); } } async function deleteDelayedTask({ triggerTaskId }) { try { clearTimeout(timerMap.get(triggerTaskId)); timerMap.delete(triggerTaskId); const db = await getDatabase("Internet-hospital"); await db.collection("order-trigger-task").deleteOne({ triggerTaskId }); } catch (error) { console.log("========>error", error); } } // 当服务器重启时,从数据库中恢复延迟任务 async function recoverDelayedTasks() { connectToMongoDB(); const db = await getDatabase("Internet-hospital"); const tasks = await db.collection("order-trigger-task").find().toArray(); for (let i = 0; i < tasks.length; i++) { await createSetTimeOut(tasks[i]); } }