如何在Laravel Cashier中查询指定日期范围内订阅或取消订阅的用户列表
问题原因
User::subscription()是单用户实例的关联调用方法,无法直接用于全局批量用户查询,所以你的写法会失效,需要用关联查询语法关联订阅表做条件筛选。
Laravel Cashier默认的subscriptions表核心字段说明:
created_at:订阅正式生效时间ends_at:订阅终止时间,主动取消、到期自动终止时该字段会被赋值,不为空即为终止状态cancelled:Cashier 10+版本新增字段,标记是否为用户主动取消
具体实现代码
先定义你需要查询的时间范围:
$startDate = '2024-01-01 00:00:00'; $endDate = '2024-01-31 23:59:59';
1. 获取指定时间范围内新完成订阅的用户列表
$subscribedUsers = User::whereHas('subscriptions', function ($query) use ($startDate, $endDate) { $query->whereBetween('created_at', [$startDate, $endDate]); })->get();
2. 获取指定时间范围内取消订阅的用户列表
$cancelledUsers = User::whereHas('subscriptions', function ($query) use ($startDate, $endDate) { $query->whereNotNull('ends_at') ->whereBetween('ends_at', [$startDate, $endDate]); // 只筛选用户主动取消的场景再加以下条件 // ->where('cancelled', 1); })->get();
3. 合并两类用户并去重的全量列表
如果需要同时返回时间范围内新增订阅、取消订阅的所有用户,直接合并条件查询即可:
$allTargetUsers = User::whereHas('subscriptions', function ($query) use ($startDate, $endDate) { $query->whereBetween('created_at', [$startDate, $endDate]) ->orWhere(function ($q) use ($startDate, $endDate) { $q->whereNotNull('ends_at') ->whereBetween('ends_at', [$startDate, $endDate]); }); })->distinct()->get();
性能优化提示
如果数据量较大,建议直接查询订阅模型再关联用户,避免关联查询的性能损耗:
$targetSubscriptions = Laravel\Cashier\Subscription::whereBetween('created_at', [$startDate, $endDate]) ->orWhere(function ($q) use ($startDate, $endDate) { $q->whereNotNull('ends_at') ->whereBetween('ends_at', [$startDate, $endDate]); }) ->with('user') // 预加载用户避免N+1问题 ->get(); // 提取去重后的用户列表 $users = $targetSubscriptions->pluck('user')->unique();
内容的提问来源于stack exchange,提问作者Nauman Nasir
相关产品推荐
相关产品推荐

