You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

41 lines
2.6 KiB

<?php
namespace App\Services\SupplyDemand;
use App\Models\User;
use App\Models\Message;
use App\Models\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Carbon;
class Notices
{
public static function queue($userId) {
if (!$userId) return;
DB::table('supply_demand_sms_notices')->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;
});
}
}