/** * 应用场景说明 * 震元下单分为 门店端(使用平板下单)和 支付宝小程序(使用手机下单) * 门店店下单流程: * 1.直营门店his系统挂号(社会门店在我们网页挂号),挂号时调用获取推荐医生接口,挂号完成就确定医生 * 2.用户在平板上填写资料,然后提交资料进而完成下单操作 * 支付宝小程序下单流程: * 1.用户在支付宝小程序上填写资料下单 * 2. 调用下单接口,下单接口会调用获取推荐医生接口,下单完成就确定医生 * * 由于门店段挂号完成到填写资料下单期间 存在时间差(填写资料过程中,未被计入进行中的订单数),导致实时统计医生进行中的订单数不准确,从而导致个别医生短时间内被推荐次数过多,进而某一刻接到大量咨询订单,而其他医生则空闲 * 因此需要记录一分钟内获取推荐医生的数量,辅助统计医生进行中的订单数,从而保证医生接单的公平性 */ // 用于记录一分钟内获取推荐医生的数量 // 数据结构:Map const doctorCountInOneMinute = new Map(); /** * 清理过期的医生推荐记录(超过一分钟的数据) */ function cleanExpiredDoctorRecords() { const oneMinuteAgo = Date.now() - 60 * 1000; for (const [doctorNo, timestamps] of doctorCountInOneMinute.entries()) { // 过滤掉超过一分钟的时间戳 const validTimestamps = timestamps.filter(timestamp => timestamp > oneMinuteAgo); if (validTimestamps.length === 0) { // 如果没有有效的时间戳,删除该医生的记录 doctorCountInOneMinute.delete(doctorNo); } else { // 更新为有效的时间戳 doctorCountInOneMinute.set(doctorNo, validTimestamps); } } } /** * 记录医生被推荐的情况 * @param {string} doctorNo - 医生工号 */ function recordDoctorRecommendation(doctorNo) { const currentTime = Date.now(); // 先清理过期数据 cleanExpiredDoctorRecords(); // 记录当前医生的推荐时间 if (doctorCountInOneMinute.has(doctorNo)) { doctorCountInOneMinute.get(doctorNo).push(currentTime); } else { doctorCountInOneMinute.set(doctorNo, [currentTime]); } } /** * 根据医生工号查询一分钟内的推荐次数 * @param {string} doctorNo - 医生工号 * @returns {number} 推荐次数 */ function getDoctorRecommendationCount(doctorNo) { // 先清理过期数据 cleanExpiredDoctorRecords(); return doctorCountInOneMinute.has(doctorNo) ? doctorCountInOneMinute.get(doctorNo).length : 0; } /** * 获取所有医生一分钟内的推荐统计 * @returns {Object} 统计信息 */ function getAllDoctorRecommendationStats() { // 先清理过期数据 cleanExpiredDoctorRecords(); const stats = {}; for (const [doctorNo, timestamps] of doctorCountInOneMinute.entries()) { stats[doctorNo] = { count: timestamps.length, timestamps: [...timestamps] // 返回副本 }; } return stats; } module.exports = { recordDoctorRecommendation, getDoctorRecommendationCount, getAllDoctorRecommendationStats };