Laravel 查询recorded为19天前的用户记录逻辑不生效问题
问题排查
原有查询的核心错误
- 时间逻辑完全颠倒:
now()->addDays(19)是取当前时间往后推19天的未来时间点,你的查询是匹配recorded等于这个未来时间的用户,不可能命中任何已经产生的历史用户记录,完全不符合"满19天"的业务要求。 - 精确匹配逻辑漏用户:哪怕你把时间改成减19天,直接用
=匹配也会有问题:recorded一般是带时分秒的datetime类型,而cron是每日执行一次,精确匹配某一个时间点会漏掉所有recorded时分秒和cron执行时间不一致的用户,永远触发不了。
修复方案
根据你的业务规则(recorded日期+19天的当天发邮件),推荐两种实现方式:
方式1:按日期匹配(适合每日固定时间跑cron的场景)
直接匹配recorded的日期部分等于19天前的日期,完美匹配你给的示例逻辑:
App\Users::query() ->where('status', 'followup') ->whereDate('recorded', now()->subDays(19)) // 建议新增followup_email_sent_at字段标记发送状态,避免重复发邮件,加如下条件 // ->whereNull('followup_email_sent_at') ->get();
发送完邮件后记得更新对应用户的followup_email_sent_at字段为当前时间,防止重复发送。
方式2:范围匹配(更稳妥,支持补漏)
如果担心cron某一天执行失败漏发,可以用范围查询加发送状态标记,就算延后几天补跑cron也能把之前漏的用户都捞出来:
App\Users::query() ->where('status', 'followup') ->where('recorded', '<=', now()->subDays(19)) ->whereNull('followup_email_sent_at') ->get();
内容的提问来源于stack exchange,提问作者BigJobbies
相关产品推荐
相关产品推荐

