insertOrIgnore(['user_id' => $userId, 'created_at' => now(), 'updated_at' => now()]); DB::table('supply_demand_sms_notices')->where('user_id', $userId)->whereNull('pending_at')->update(['pending_at' => now(), 'attempts' => 0, 'updated_at' => now()]); } public static function deliver($userId, callable $sender = null) { $settings = Settings::all(); if ((int) $settings['sms_enabled'] !== 1) return false; return DB::transaction(function () use ($userId, $settings, $sender) { $row = DB::table('supply_demand_sms_notices')->where('user_id', $userId)->lockForUpdate()->first(); if (!$row || !$row->pending_at || $row->attempts >= 3) return false; if ($row->sent_date !== now()->toDateString()) $row->sent_today = 0; if ($row->sent_today >= (int) $settings['sms_daily_limit']) return false; if ($row->last_sent_at && Carbon::parse($row->last_sent_at)->addMinutes((int) $settings['sms_interval_minutes'])->isFuture()) return false; $user = User::find($userId); $hasUnread = Message::where('to_user_id', $userId)->where('is_read', 0)->whereHas('supplyDemand', function ($q) use ($userId) { $q->where('user_id', $userId); })->exists(); if (!$user || !$hasUnread) { DB::table('supply_demand_sms_notices')->where('id', $row->id)->update(['pending_at' => null]); return false; } $content = (Config::getValueByKey('sms_sign') ?: '') . $settings['sms_content']; try { $ok = ($sender ?: function ($mobile, $text) { return ymSms($mobile, $text, 0, 'supply_demand', null); })($user->getRawOriginal('mobile'), $content); } catch (\Throwable $e) { $ok = false; } DB::table('supply_demand_sms_notices')->where('id', $row->id)->update([ 'pending_at' => $ok ? null : $row->pending_at, 'last_sent_at' => $ok ? now() : $row->last_sent_at, 'sent_date' => now()->toDateString(), 'sent_today' => $row->sent_today + ($ok ? 1 : 0), 'attempts' => $row->attempts + 1, 'last_error' => $ok ? null : '短信发送失败,请检查短信通道;三次失败后可后台重试', 'updated_at' => now(), ]); return (bool) $ok; }); } }