6
0
Fork 0
jiqu-library-server/app/Services/SmsCodeService.php

105 lines
2.6 KiB
PHP

<?php
namespace App\Services;
use App\Exceptions\BizException;
use App\Models\SmsCode;
use App\Models\User;
use Illuminate\Contracts\Cache\Repository as Cache;
class SmsCodeService
{
/**
* @var int
*/
protected $expires = 300;
/**
* @param \Illuminate\Contracts\Cache\Repository $cache
*/
public function __construct(
protected Cache $cache,
) {
}
/**
* 发送短信验证码
*
* @param string $phone
* @param int $type
* @param string $code
* @param int $decaySeconds
* @return \App\Models\SmsCode
*
* @throws \App\Exceptions\BizException
*/
public function send(
string $phone,
int $type,
string $code,
int $decaySeconds = 60,
): SmsCode {
if (! in_array($type, SmsCode::$allowedTypes)) {
throw new BizException(__('Invalid verification code type'));
}
$user = User::where('phone', $phone)->first();
switch ($type) {
case SmsCode::TYPE_REGISTER:
if ($user) {
throw new BizException(__('The phone number is already registered'));
}
break;
case SmsCode::TYPE_LOGIN:
case SmsCode::TYPE_RESET_PASSWORD:
case SmsCode::TYPE_SET_WALLET_PASSWORD:
if ($user === null) {
throw new BizException('手机号未注册');
}
break;
}
if (! $this->cache->add("sms_lock_{$type}_{$phone}", 1, $decaySeconds)) {
throw new BizException(__('Sending too frequently, please try again later'));
}
return SmsCode::create([
'phone' => $phone,
'code' => $code,
'type' => $type,
'expires_at' => now()->addSeconds($this->expires),
'user_id' => $user?->id,
]);
}
/**
* 校验验证码是否正确
*
* @param string $phone
* @param int $type
* @param string $code
* @return void
*
* @throws \App\Exceptions\BizException
*/
public function validate(string $phone, int $type, string $code): void
{
$smsCode = SmsCode::where('phone', $phone)
->where('type', $type)
->latest('id')
->first();
if ($smsCode === null || $smsCode->code !== $code || $smsCode->isInvalid()) {
throw new BizException(__('Invalid verification code'));
}
$smsCode->update([
'is_use' => true,
]);
}
}