219 lines
6.6 KiB
PHP
219 lines
6.6 KiB
PHP
|
<?php
|
|||
|
// +----------------------------------------------------------------------
|
|||
|
// | likeshop100%开源免费商用商城系统
|
|||
|
// +----------------------------------------------------------------------
|
|||
|
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
|||
|
// | 开源版本可自由商用,可去除界面版权logo
|
|||
|
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
|||
|
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
|||
|
// | gitee下载:https://gitee.com/likeshop_gitee
|
|||
|
// | github下载:https://github.com/likeshop-github
|
|||
|
// | 访问官网:https://www.likeshop.cn
|
|||
|
// | 访问社区:https://home.likeshop.cn
|
|||
|
// | 访问手册:http://doc.likeshop.cn
|
|||
|
// | 微信公众号:likeshop技术社区
|
|||
|
// | likeshop团队 版权所有 拥有最终解释权
|
|||
|
// +----------------------------------------------------------------------
|
|||
|
// | // +----------------------------------------------------------------------
|
|||
|
// | likeadmin快速开发前后端分离管理后台(PHP版)
|
|||
|
// +----------------------------------------------------------------------
|
|||
|
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
|||
|
// | 开源版本可自由商用,可去除界面版权logo
|
|||
|
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
|
|||
|
// | github下载:https://github.com/likeshop-github/likeadmin
|
|||
|
// | 访问官网:https://www.likeadmin.cn
|
|||
|
// | likeadmin团队 版权所有 拥有最终解释权
|
|||
|
// +----------------------------------------------------------------------
|
|||
|
// | author: likeadminTeam
|
|||
|
// +----------------------------------------------------------------------
|
|||
|
// +----------------------------------------------------------------------
|
|||
|
namespace app\common\service\sms;
|
|||
|
|
|||
|
use app\common\enum\notice\NoticeEnum;
|
|||
|
use app\common\enum\notice\SmsEnum;
|
|||
|
use app\common\enum\YesNoEnum;
|
|||
|
use app\common\model\Notice;
|
|||
|
use app\common\model\notice\SmsLog;
|
|||
|
use app\common\service\ConfigService;
|
|||
|
|
|||
|
/**
|
|||
|
* 短信驱动
|
|||
|
* Class SmsDriver
|
|||
|
* @package app\common\service\sms
|
|||
|
*/
|
|||
|
class SmsDriver
|
|||
|
{
|
|||
|
/**
|
|||
|
* 错误信息
|
|||
|
* @var
|
|||
|
*/
|
|||
|
protected $error = null;
|
|||
|
|
|||
|
/**
|
|||
|
* 默认短信引擎
|
|||
|
* @var
|
|||
|
*/
|
|||
|
protected $defaultEngine;
|
|||
|
|
|||
|
/**
|
|||
|
* 短信引擎
|
|||
|
* @var
|
|||
|
*/
|
|||
|
protected $engine;
|
|||
|
|
|||
|
/**
|
|||
|
* 架构方法
|
|||
|
* SmsDriver constructor.
|
|||
|
*/
|
|||
|
public function __construct()
|
|||
|
{
|
|||
|
// 初始化
|
|||
|
$this->initialize();
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @notes 初始化
|
|||
|
* @return bool
|
|||
|
* @author 段誉
|
|||
|
* @date 2022/9/15 16:29
|
|||
|
*/
|
|||
|
public function initialize()
|
|||
|
{
|
|||
|
try {
|
|||
|
$defaultEngine = ConfigService::get('sms', 'engine', false);
|
|||
|
if($defaultEngine === false) {
|
|||
|
throw new \Exception('请开启短信配置');
|
|||
|
}
|
|||
|
$this->defaultEngine = $defaultEngine;
|
|||
|
$classSpace = __NAMESPACE__ . '\\engine\\' . ucfirst(strtolower($defaultEngine)) . 'Sms';
|
|||
|
if (!class_exists($classSpace)) {
|
|||
|
throw new \Exception('没有相应的短信驱动类');
|
|||
|
}
|
|||
|
$engineConfig = ConfigService::get('sms', strtolower($defaultEngine), false);
|
|||
|
if($engineConfig === false) {
|
|||
|
throw new \Exception($defaultEngine . '未配置');
|
|||
|
}
|
|||
|
if ($engineConfig['status'] != 1) {
|
|||
|
throw new \Exception('短信服务未开启');
|
|||
|
}
|
|||
|
$this->engine = new $classSpace($engineConfig);
|
|||
|
if(!is_null($this->engine->getError())) {
|
|||
|
throw new \Exception($this->engine->getError());
|
|||
|
}
|
|||
|
return true;
|
|||
|
} catch (\Exception $e) {
|
|||
|
$this->error = $e->getMessage();
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @notes 获取错误信息
|
|||
|
* @return null
|
|||
|
* @author 段誉
|
|||
|
* @date 2022/9/15 16:29
|
|||
|
*/
|
|||
|
public function getError()
|
|||
|
{
|
|||
|
return $this->error;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @notes 发送短信
|
|||
|
* @param $mobile
|
|||
|
* @param $data
|
|||
|
* @return false
|
|||
|
* @author 段誉
|
|||
|
* @date 2022/9/15 16:29
|
|||
|
*/
|
|||
|
public function send($mobile, $data)
|
|||
|
{
|
|||
|
try {
|
|||
|
// 发送频率限制
|
|||
|
$this->sendLimit($mobile);
|
|||
|
// 开始发送
|
|||
|
$result = $this->engine
|
|||
|
->setMobile($mobile)
|
|||
|
->setTemplateId($data['template_id'])
|
|||
|
->setTemplateParams($data['params'])
|
|||
|
->send();
|
|||
|
if(false === $result) {
|
|||
|
throw new \Exception($this->engine->getError());
|
|||
|
}
|
|||
|
return $result;
|
|||
|
} catch(\Exception $e) {
|
|||
|
$this->error = $e->getMessage();
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @notes 发送频率限制
|
|||
|
* @param $mobile
|
|||
|
* @throws \Exception
|
|||
|
* @author 段誉
|
|||
|
* @date 2022/9/15 16:29
|
|||
|
*/
|
|||
|
public function sendLimit($mobile)
|
|||
|
{
|
|||
|
$smsLog = SmsLog::where([
|
|||
|
['mobile', '=', $mobile],
|
|||
|
['send_status', '=', SmsEnum::SEND_SUCCESS],
|
|||
|
['scene_id', 'in', NoticeEnum::SMS_SCENE],
|
|||
|
])
|
|||
|
->order('send_time', 'desc')
|
|||
|
->findOrEmpty()
|
|||
|
->toArray();
|
|||
|
if(!empty($smsLog) && ($smsLog['send_time'] > time() - 60)) {
|
|||
|
throw new \Exception('同一手机号1分钟只能发送1条短信');
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @notes 校验手机验证码
|
|||
|
* @param $mobile
|
|||
|
* @param $code
|
|||
|
* @return bool
|
|||
|
* @author 段誉
|
|||
|
* @date 2022/9/15 16:29
|
|||
|
*/
|
|||
|
public function verify($mobile, $code, $sceneId = 0)
|
|||
|
{
|
|||
|
$where = [
|
|||
|
['mobile', '=', $mobile],
|
|||
|
['send_status', '=', SmsEnum::SEND_SUCCESS],
|
|||
|
['scene_id', 'in', NoticeEnum::SMS_SCENE],
|
|||
|
['is_verify', '=', YesNoEnum::NO],
|
|||
|
];
|
|||
|
|
|||
|
if (!empty($sceneId)) {
|
|||
|
$where[] = ['scene_id', '=', $sceneId];
|
|||
|
}
|
|||
|
|
|||
|
$smsLog = SmsLog::where($where)
|
|||
|
->order('send_time', 'desc')
|
|||
|
->findOrEmpty();
|
|||
|
|
|||
|
// 没有验证码 或 最新验证码已校验 或 已过期(有效期:5分钟)
|
|||
|
if($smsLog->isEmpty() || $smsLog->is_verify || ($smsLog->send_time < time() - 5 * 60) ) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// 更新校验状态
|
|||
|
if($smsLog->code == $code) {
|
|||
|
$smsLog->check_num = $smsLog->check_num + 1;
|
|||
|
$smsLog->is_verify = YesNoEnum::YES;
|
|||
|
$smsLog->save();
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
// 更新验证次数
|
|||
|
$smsLog->check_num = $smsLog->check_num + 1;
|
|||
|
$smsLog->save();
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|