Commit 118cf262 authored by wangzhengwen's avatar wangzhengwen

5.21 sms

parent 8b43c884
......@@ -13,6 +13,7 @@ use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Dysmsapi\Dysmsapi;
use think\facade\Cache;
use think\Facade\Db;
/**
......@@ -26,6 +27,9 @@ class SendSms
*/
private $cache_key = '';
const TOKEN_PREFIX = 'sms_token:';
/**
* 短信接口配置
* sms_url 接口地址
......@@ -185,86 +189,112 @@ class SendSms
* @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();
$res_code = 0;
$status = 0;
$defaultConfig = vconfig();
$this->config = array_merge($this->config, $defaultConfig);
//屏蔽频繁发送
$arr = cache($this->cache_key);
$lent = $lent ? $lent : vconfig('sms_times');
// 验证短信服务是否开启
if (!$this->config['sms_state']) {
return $this->logAndReturn('短信接口未开启', $mobile, $code, 0, 0);
}
if(isset($arr['time']) && ($time-$arr['time'])<$lent) return ['msg'=>'发送过于频繁!','code'=>0];
//整合配置
$this->config = array_merge($this->config, vconfig());
if(!$this->config['sms_state']) return ['msg'=>'短信接口未开启','code'=>0];
if(!$mobile) return ['msg'=>'手机号不能为空','code'=>0];
// 2. 频率限制检查
$lent = $lent ?: $defaultConfig['sms_times'] ?? 60; // 默认60秒间隔
$lent = (int)$lent;
$cacheKey = $this->cache_key . '_' . $mobile; // 按手机号区分频率限制
$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');
// 4. 发送短信
try {
AlibabaCloud::accessKeyClient($this->config['AccessKeyID'], $this->config['AccessKeySecret'])
->regionId('cn-hangzhou')
->asDefaultClient();
try {
// 2. 创建请求对象
$result = AlibabaCloud::rpc()
->product('Dysmsapi') // 指定产品
->version('2017-05-25') // 指定API版本
->action('SendSms') // 指定接口动作
->method('POST') // 请求方法
->host('dysmsapi.aliyuncs.com') // 服务地址
->product('Dysmsapi')
->version('2017-05-25')
->action('SendSms')
->method('POST')
->host('dysmsapi.aliyuncs.com')
->options([
'query' => [
'PhoneNumbers' => $mobile, // 手机号
'SignName' => '重庆流速科技', // 短信签名
'TemplateCode' => $template_id, // 短信模板CODE
'TemplateParam' => json_encode([ // 模板参数(JSON格式)
'code' => $code,
// 'time' => '5分钟'
]),
// 'OutId' => 'your_out_id', // 可选:外部流水号(用于回调识别)
// 'SmsUpExtendCode' => '123', // 可选:上行短信扩展码
'PhoneNumbers' => $mobile,
'SignName' => $this->config['sms_sign_name'] ?? '重庆流速科技',
'TemplateCode' => $templateId,
'TemplateParam' => json_encode(['code' => $code]),
],
])
->connectTimeout(10) // 连接超时(秒)
->timeout(10) // 请求超时(秒)
->request(); // 执行请求
->connectTimeout(10)
->timeout(10)
->request();
// 5. 处理结果
if ($result['Code'] === 'OK') {
$res_code = 200;
$errMsg = 'success';
$status = 1;
} else {
$res_code = 500;
$errMsg = $result['Message'];
}
// 成功发送后更新缓存
cache($cacheKey, ['time' => $time]);
cache($this->cache_key,['time'=>$time]);
} catch (ClientException $e) {
$res_code = $e->getCode();
$errMsg = $e->getMessage();
// 存储验证码,有效期与发送间隔相同
$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 {
$this->clear_time_cache();
} catch (ServerException $e) {
$res_code = $e->getCode();
$errMsg = $e->getMessage();
return $this->logAndReturn($result['Message'] ?? '短信发送失败', $mobile, $code, 500, 0);
}
} catch (ClientException | ServerException $e) {
$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();
return ['msg'=>$errMsg,'code'=>$status];
/**
* 记录日志并返回结果
*/
private function logAndReturn(string $message, int $mobile, int $code, int $resCode, int $status): array
{
$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