123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- <?php
- namespace App\Services;
- use App\Exceptions\SmsException;
- use App\Models\SmsRecord;
- use Illuminate\Support\Facades\Redis;
- use Illuminate\Support\Str;
- use Overtrue\EasySms\EasySms;
- use Overtrue\EasySms\Exceptions\Exception;
- use Overtrue\EasySms\Exceptions\NoGatewayAvailableException;
- class SmsService
- {
- const EVENT_LOGIN = 100;
- const DEFAULT_SMS_CODE_LENGTH = 4;
- const DEFAULT_SMS_CODE_EXP_TIME = 120;
- const EVENTS_TO_TEMPLATE = [
- //'login' => 377532, //好邻盟短信验证码为:{1},请在{2}分钟内输入,如非本人操作,请忽略本短信
- // 'login' => "SMS_187241612",
- 'login' => "SMS_227262168",
- // 'forget' => 377532, //好邻盟短信验证码为:{1},请在{2}分钟内输入,如非本人操作,请忽略本短信
- // 'forget' => "SMS_187241612",
- 'forget' => "SMS_227262168",
- ];
- const EVENT_ITEM_FUNCTION = [
- ];
- /**
- * 获取easySms配置
- * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
- */
- static public function getEasySmsConfig()
- {
- return config('easysms');
- }
- /**
- * 获取 easySms 实例
- * @return EasySms
- */
- static public function easySms()
- {
- return new EasySms(self::getEasySmsConfig());
- }
- static public function send(int $mobile, string $event, array $eventData, $user = null)
- {
- try {
- self::verifySmsEvent($event);
- $templateId = self::getTemplateIdByEvent($event);
- // if(app()->isLocal()){
- // $smsCode = 1234 ;
- // $result = true;
- // }else{
- $smsCode = self::getSmsCode();
- $result = self::easySms()->send($mobile, [
- 'template' => $templateId,
- 'content' => 'null',
- 'data' => [
- 'code' => $smsCode,
- // 'expTime' => 10,
- ]
- ],['aliyun']);
- // }
- //$result = true;
- //缓存验证码
- $verifyKey = self::getVerifyKey();
- self::cacheSmsCodeByVerifyKey($mobile, $smsCode, $verifyKey);
- //存入发送记录
- self::storeSmsRecord($mobile, $event, $smsCode, $verifyKey, $result);
- return [
- 'verifyKey' => $verifyKey,
- 'code' => $smsCode,
- ];
- } catch (SmsException $e) {
- return ['error' => $e->getMessage()];
- } catch (NoGatewayAvailableException $e) {
- // return ['error' => json_encode($e)];
- return ['error' => '发送短信失败'];
- } catch (Exception $e) {
- return ['error' => '发送短信失败'];
- }
- }
- /**
- * 生成随机字符串用户校验验证码
- * @param int $length
- * @return string
- */
- static public function getVerifyKey(int $length = 10)
- {
- return Str::random($length);
- }
- /**
- * 生成短信验证码
- * @param int $length
- * @return int
- */
- static public function getSmsCode(int $length = self::DEFAULT_SMS_CODE_LENGTH)
- {
- return rand(1000, 9999);
- }
- /**
- * 根据验证码,verifyKey 校验是否正确
- * @param string $verifyKey
- * @param string $smsCode
- * @return bool
- * @throws SmsException
- */
- static public function checkSmsCodeByVerifyKey(string $verifyKey, string $smsCode)
- {
- if (!RedisService::redis()->exists('smsCode:verifyCode' . $verifyKey)) {
- throw new SmsException('验证码已过期');
- }
- $record = RedisService::redis()->get('smsCode:verifyCode' . $verifyKey);
- if (!json_decode($record, true)) {
- throw new SmsException('验证码解析失败');
- }
- $record = json_decode($record, true);
- if ($smsCode != $record['smsCode']) {
- throw new SmsException('验证码错误');
- }
- RedisService::redis()->del('smsCode:verifyCode' . $verifyKey);
- return true;
- }
- /**
- * 缓存短信验证码
- * @param int $mobile
- * @param string $smsCode
- * @param string $verifyKey
- * @param int $expTime
- * @return mixed
- */
- static public function cacheSmsCodeByVerifyKey(int $mobile, string $smsCode, string $verifyKey, int $expTime = self::DEFAULT_SMS_CODE_EXP_TIME)
- {
- return RedisService::redis()->SETEX('smsCode:verifyCode' . $verifyKey, $expTime, json_encode(['mobile' => $mobile, 'smsCode' => $smsCode]));
- }
- /**
- * 根据事件获取 短信模板ID
- * @param string $event
- * @return string
- * @throws SmsException
- */
- static public function getTemplateIdByEvent(string $event)
- {
- self::verifySmsEvent($event);
- return self::EVENTS_TO_TEMPLATE[$event];
- }
- /**
- * 验证发送事件
- * @param string $event
- * @return bool
- * @throws SmsException
- */
- static public function verifySmsEvent(string $event)
- {
- if (!array_key_exists($event, self::EVENTS_TO_TEMPLATE)) {
- throw new SmsException('事件类型错误');
- }
- return true;
- }
- /**
- * 将发送记录存到数据库以便调试
- * @param int $mobile
- * @param string $event
- * @param string $smsCode
- * @param string $verifyKey
- * @param $sendResult
- * @return mixed
- */
- static public function storeSmsRecord(int $mobile, string $event, string $smsCode, string $verifyKey, $sendResult)
- {
- return SmsRecord::create([
- 'mobile' => $mobile,
- 'event' => $event,
- 'sms_code' => $smsCode,
- 'verify_key' => $verifyKey,
- 'sms_result' => $sendResult
- ]);
- }
- }
|