SmsHelper.php 3.91 KB
<?php

namespace App\Helpers;

use App\Enums\UserStatusEnum;
use App\Models\SystemSmsLog;
use App\Models\User;
use Arr;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Overtrue\EasySms\Exceptions\NoGatewayAvailableException;
use Overtrue\EasySms\PhoneNumber;

class SmsHelper
{
    /**
     * @param \Overtrue\EasySms\PhoneNumber $phoneNumber
     * @param int|array|NULL                $scope
     * @return bool
     */
    public static function checkPhoneExist(PhoneNumber $phoneNumber, int|array $scope = NULL): bool
    {
        return User::phoneNumber($phoneNumber)
            ->when($scope, fn(Builder $query) => $query->whereIn('scope', Arr::wrap($scope)))
            ->exists();
    }

    /**
     * @param \Overtrue\EasySms\PhoneNumber $phoneNumber
     * @param int|array|UserStatusEnum      $status
     * @param int|array|NULL                $scope
     * @return bool
     */
    public static function checkPhoneStatus(PhoneNumber $phoneNumber, int|array|UserStatusEnum $status = 1, int|array $scope = NULL): bool
    {
        return User::phoneNumber($phoneNumber)
            ->when($scope, fn(Builder $query) => $query->whereIn('scope', Arr::wrap($scope)))
            ->whereIn('status', Arr::wrap($status))
            ->exists();
    }

    /**
     * @param int    $phone
     * @param string $area
     * @return \Overtrue\EasySms\PhoneNumber
     */
    public static function getAreaPhoneNumber(int $phone, string $area = '86'): PhoneNumber
    {
        return new PhoneNumber($phone, $area);
    }

    /**
     * @param int $length
     * @return string
     * @throws \Exception
     */
    public static function createNumberCode(int $length = 6): string
    {
        return substr((string)(random_int(0, (10 ** $length) - 1) + 10 ** $length), 1, $length);
    }

    /**
     * @param \Overtrue\EasySms\PhoneNumber $phone
     * @return bool
     */
    public static function checkPhoneLimit(PhoneNumber $phone): bool
    {
        return self::getPhoneHourCount($phone) <= 5 && self::getPhoneDayCount($phone) <= 32;
    }

    /**
     * @param \Overtrue\EasySms\PhoneNumber $phone
     * @return int
     */
    public static function getPhoneHourCount(PhoneNumber $phone): int
    {
        return DB::table('system_sms_logs')
            ->where('phone', $phone->getUniversalNumber())
            ->where('status', 'success')
            ->whereBetween('created_at', [now()->subHour()->toDateTimeString(), now()->toDateTimeString()])
            ->count();
    }

    /**
     * @param \Overtrue\EasySms\PhoneNumber $phone
     * @return int
     */
    public static function getPhoneDayCount(PhoneNumber $phone): int
    {
        return DB::table('system_sms_logs')
            ->where('phone', $phone->getUniversalNumber())
            ->where('status', 'success')
            ->whereBetween('created_at', [now()->subDay()->toDateTimeString(), now()->toDateTimeString()])
            ->count();
    }

    /**
     * @param \Overtrue\EasySms\PhoneNumber $phone
     * @param string                        $code
     * @param string                        $type
     * @return string
     */
    public static function getSmsKey(string $type, PhoneNumber $phone, string $code, ?string $platform = ''): string
    {
        return collect(['sms', $phone->getUniversalNumber(), $platform, $type, $code])->filter()->implode(':');
    }

    /**
     * @param string $smsKey
     * @return bool
     * @throws \RedisException
     */
    public static function checkSmsKey(string $smsKey): bool
    {
        return Redis::client()->exists($smsKey);
    }

    /**
     * @param string $smsKey
     * @param int    $second
     * @param string $value
     * @return bool
     * @throws \RedisException
     */
    public static function saveSmsKey(string $smsKey, int $second = 300, string $value = ''): bool
    {
        return Redis::client()->setex($smsKey, $second, $value);
    }
}