where('num', '>', 0)->orderBy('id')->limit($this->limit)->get(); $logs = $logs->groupBy('task_id'); foreach ($logs as $taskId => $taskLogs) { $nowTime = now(); $task = CouponSendTask::find($taskId); $coupon = Coupon::find($task->coupon_id); //如果优惠券限量,则获取优惠券余量,只发送前面的人; $failedLogs = collect([]); if ($coupon->limit > 0 && $coupon->stock < ($taskLogs->count() * $task->num)) { $failedLogs = $taskLogs->slice($coupon->stock); $taskLogs = $taskLogs->slice(0, $coupon->stock); } if ($coupon->use_start_at && $coupon->use_end_at) { $useStartAt = $coupon->use_start_at; $useEndAt = $coupon->use_end_at; } else { $useStartAt = now(); $useEndAt = now()->addDays($coupon->use_day); } //批量插入用户优惠券 $insertUserCoupons = []; foreach ($taskLogs as $taskLog) { for ($i=0; $i< $taskLog->num; $i++) { $insertUserCoupons[] = [ 'user_id' => $taskLog->user_id, 'coupon_id' => $taskLog->coupon_id, 'coupon_name' => $coupon->name, 'coupon_type' => $coupon->type, 'coupon_amount' => (int) bcmul($coupon->amount, 100), 'coupon_threshold'=> (int) bcmul($coupon->threshold, 100), 'use_start_at' => $useStartAt, 'use_end_at' => $useEndAt, 'status' => 0, 'created_at' => $nowTime, 'updated_at' => $nowTime, ]; } } try { DB::beginTransaction(); count($insertUserCoupons) > 0 && UserCoupon::insert($insertUserCoupons); //更新任务日志状态; CouponTaskLog::whereIn('id', $taskLogs->pluck('id')->toArray())->update(['status'=>2]); $failedLogs->count() == 0 || CouponTaskLog::whereIn('id', $failedLogs->pluck('id')->toArray())->update(['status'=>3, 'remarks'=>'库存余量不足']); //更新任务对应券发送量,余量; $coupon->increment('sent', $taskLogs->count()); if ($coupon->limit > 0) {//限量才减少余量 $coupon->decrement('stock', $taskLogs->count()); } //更新如果是任务最后一批,更新任务状态; $taskTotalnum = CouponTaskLog::where('task_id', $taskId)->where('num', '>', 0)->count(); $taskDidnum = CouponTaskLog::where('task_id', $taskId)->where('num', '>', 0)->where('status', '>', 0)->count(); if ($taskTotalnum == $taskDidnum) { $task->update(['status' => 3]); } DB::commit(); } catch (Throwable $th) { DB::rollBack(); report($th); } } $this->info('执行成功'); return Command::SUCCESS; } }