Commit 118cf262 authored by wangzhengwen's avatar wangzhengwen

5.21 sms

parent 8b43c884
...@@ -13,6 +13,7 @@ use AlibabaCloud\Client\AlibabaCloud; ...@@ -13,6 +13,7 @@ use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException; use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException; use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Dysmsapi\Dysmsapi; use AlibabaCloud\Dysmsapi\Dysmsapi;
use think\facade\Cache;
use think\Facade\Db; use think\Facade\Db;
/** /**
...@@ -26,6 +27,9 @@ class SendSms ...@@ -26,6 +27,9 @@ class SendSms
*/ */
private $cache_key = ''; private $cache_key = '';
const TOKEN_PREFIX = 'sms_token:';
/** /**
* 短信接口配置 * 短信接口配置
* sms_url 接口地址 * sms_url 接口地址
...@@ -185,86 +189,112 @@ class SendSms ...@@ -185,86 +189,112 @@ class SendSms
* @return array * @return array
*/ */
public function aliyun_send(int $mobile = 0, int $code = 0, string $tpid = '', string $tips = '', int $lent = 0) public function aliyun_send(int $mobile = 0, int $code = 0, string $tpid = '', string $tips = '', int $lent = 0): array
{ {
$errMsg = ''; // 1. 参数验证与初始化
$time = time(); $time = time();
$res_code = 0; $defaultConfig = vconfig();
$status = 0; $this->config = array_merge($this->config, $defaultConfig);
//屏蔽频繁发送 // 验证短信服务是否开启
$arr = cache($this->cache_key); if (!$this->config['sms_state']) {
$lent = $lent ? $lent : vconfig('sms_times'); return $this->logAndReturn('短信接口未开启', $mobile, $code, 0, 0);
}
if(isset($arr['time']) && ($time-$arr['time'])<$lent) return ['msg'=>'发送过于频繁!','code'=>0]; // 2. 频率限制检查
//整合配置 $lent = $lent ?: $defaultConfig['sms_times'] ?? 60; // 默认60秒间隔
$this->config = array_merge($this->config, vconfig()); $lent = (int)$lent;
if(!$this->config['sms_state']) return ['msg'=>'短信接口未开启','code'=>0]; $cacheKey = $this->cache_key . '_' . $mobile; // 按手机号区分频率限制
if(!$mobile) return ['msg'=>'手机号不能为空','code'=>0];
$lastSend = cache($cacheKey);
if (isset($lastSend['time']) && ($time - $lastSend['time']) < $lent) {
return $this->logAndReturn('发送过于频繁', $mobile, $code, 0, 0);
}
// 3. 准备短信模板
$templateId = $tpid ?: $defaultConfig['sms_template_id'] ?? '';
if (empty($templateId)) {
return $this->logAndReturn('短信模板ID未配置', $mobile, $code, 0, 0);
}
if(!$code) return ['msg'=>'短信验证码不能为空','code'=>0];
$template_id = $tpid ? $tpid : vconfig('sms_template_id');
AlibabaCloud::accessKeyClient($this->config['AccessKeyID'], $this->config['AccessKeySecret'])
->regionId('cn-hangzhou')
->asDefaultClient();
// 4. 发送短信
try { try {
// 2. 创建请求对象 AlibabaCloud::accessKeyClient($this->config['AccessKeyID'], $this->config['AccessKeySecret'])
->regionId('cn-hangzhou')
->asDefaultClient();
$result = AlibabaCloud::rpc() $result = AlibabaCloud::rpc()
->product('Dysmsapi') // 指定产品 ->product('Dysmsapi')
->version('2017-05-25') // 指定API版本 ->version('2017-05-25')
->action('SendSms') // 指定接口动作 ->action('SendSms')
->method('POST') // 请求方法 ->method('POST')
->host('dysmsapi.aliyuncs.com') // 服务地址 ->host('dysmsapi.aliyuncs.com')
->options([ ->options([
'query' => [ 'query' => [
'PhoneNumbers' => $mobile, // 手机号 'PhoneNumbers' => $mobile,
'SignName' => '重庆流速科技', // 短信签名 'SignName' => $this->config['sms_sign_name'] ?? '重庆流速科技',
'TemplateCode' => $template_id, // 短信模板CODE 'TemplateCode' => $templateId,
'TemplateParam' => json_encode([ // 模板参数(JSON格式) 'TemplateParam' => json_encode(['code' => $code]),
'code' => $code,
// 'time' => '5分钟'
]),
// 'OutId' => 'your_out_id', // 可选:外部流水号(用于回调识别)
// 'SmsUpExtendCode' => '123', // 可选:上行短信扩展码
], ],
]) ])
->connectTimeout(10) // 连接超时(秒) ->connectTimeout(10)
->timeout(10) // 请求超时(秒) ->timeout(10)
->request(); // 执行请求 ->request();
// 5. 处理结果
if ($result['Code'] === 'OK') { if ($result['Code'] === 'OK') {
$res_code = 200; // 成功发送后更新缓存
$errMsg = 'success'; cache($cacheKey, ['time' => $time]);
$status = 1;
// 存储验证码,有效期与发送间隔相同
$verificationKey = self::TOKEN_PREFIX . $mobile;
Cache::set($verificationKey, $code, $lent);
// 记录日志
$message = '您的验证码为:' . $code . ',请勿泄露于他人!';
$this->logSms($mobile, $message, $code, $time, 'success', 200, 1);
return ['msg' => '发送成功', 'code' => 1];
} else { } else {
$res_code = 500; $this->clear_time_cache();
$errMsg = $result['Message']; return $this->logAndReturn($result['Message'] ?? '短信发送失败', $mobile, $code, 500, 0);
} }
} catch (ClientException | ServerException $e) {
cache($this->cache_key,['time'=>$time]);
} catch (ClientException $e) {
$res_code = $e->getCode();
$errMsg = $e->getMessage();
$this->clear_time_cache();
} catch (ServerException $e) {
$res_code = $e->getCode();
$errMsg = $e->getMessage();
$this->clear_time_cache(); $this->clear_time_cache();
return $this->logAndReturn($e->getMessage(), $mobile, $code, $e->getCode(), 0);
} }
}
$message = '您的验证码为:'.$code.',请勿泄露于他人!'; /**
* 记录短信日志
*/
private function logSms($mobile, $message, $code, $time, $errMsg, $resCode, $status): void
{
$word = function_exists('mb_strlen') ? mb_strlen($message, 'utf8') : strlen($message);
$word = function_exists('mb_strlen') ? mb_strlen($message,'utf8') : 0; Db::name('system_sms')->insert([
'mobile' => $mobile,
'message' => $message,
'word' => $word,
'editor' => 'api',
'sendtime' => $time,
'code' => $code,
'err_msg' => $errMsg,
'res_code' => $resCode,
'status' => $status
]);
}
$data = ['mobile'=> $mobile,'message'=>$message,'word'=>$word, /**
'editor'=>'api','sendtime'=>$time,'code'=>$code, * 记录日志并返回结果
'err_msg'=>$errMsg,'res_code'=>$res_code,'status'=>$status,]; */
Db::name('system_sms')->data($data)->insert(); private function logAndReturn(string $message, int $mobile, int $code, int $resCode, int $status): array
return ['msg'=>$errMsg,'code'=>$status]; {
$this->logSms($mobile, $message, $code, time(), $message, $resCode, $status);
return ['msg' => $message, 'code' => $status];
} }
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment