Files
CKB-Interface/application/store/service/SmsService.php
2026-03-24 10:39:16 +08:00

195 lines
5.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\store\service;
use think\Cache;
use think\facade\Log;
/**
* 短信服务类(阿里云)
* Class SmsService
* @package app\store\service
*/
class SmsService
{
// 阿里云短信配置(需要在配置文件中设置)
private $accessKeyId;
private $accessKeySecret;
private $signName;
private $templateCode;
public function __construct()
{
// 从配置文件读取阿里云短信配置
$config = config('aliyun_sms');
$this->accessKeyId = $config['access_key_id'] ?? '';
$this->accessKeySecret = $config['access_key_secret'] ?? '';
$this->signName = $config['sign_name'] ?? '数智员工';
$this->templateCode = $config['template_code'] ?? '';
}
/**
* 发送短信验证码
* @param string $mobile 手机号
* @param string $type 验证码类型login/register/reset
* @return array
*/
public function sendVerificationCode($mobile, $type = 'login')
{
// 验证手机号格式
if (!$this->validateMobile($mobile)) {
return ['success' => false, 'message' => '手机号格式不正确'];
}
// 检查发送频率限制60秒内只能发送一次
$cacheKey = 'sms_limit_' . $mobile;
if (Cache::has($cacheKey)) {
$lastSendTime = Cache::get($cacheKey);
$remainingTime = 60 - (time() - $lastSendTime);
if ($remainingTime > 0) {
return ['success' => false, 'message' => "{$remainingTime}秒后再试"];
}
}
// 生成6位随机验证码
$code = $this->generateCode();
// 存储验证码到缓存5分钟有效期
$verifyKey = 'sms_code_' . $mobile . '_' . $type;
Cache::set($verifyKey, $code, 300);
// 记录发送时间限制
Cache::set($cacheKey, time(), 60);
// 调用阿里云短信接口发送验证码
$result = $this->sendSms($mobile, $code);
if ($result['success']) {
Log::info("短信验证码发送成功", [
'mobile' => $mobile,
'type' => $type,
'code' => $code // 开发环境记录,生产环境应删除
]);
return [
'success' => true,
'message' => '验证码发送成功',
'data' => [
'expire_time' => 300, // 5分钟
'mobile' => $this->maskMobile($mobile)
]
];
} else {
return [
'success' => false,
'message' => $result['message'] ?? '发送失败,请稍后重试'
];
}
}
/**
* 验证短信验证码
* @param string $mobile 手机号
* @param string $code 验证码
* @param string $type 验证码类型
* @return array
*/
public function verifyCode($mobile, $code, $type = 'login')
{
$verifyKey = 'sms_code_' . $mobile . '_' . $type;
$savedCode = Cache::get($verifyKey);
if (empty($savedCode)) {
return ['success' => false, 'message' => '验证码已过期或不存在'];
}
if ($savedCode !== $code) {
return ['success' => false, 'message' => '验证码错误'];
}
// 验证成功后删除验证码
Cache::rm($verifyKey);
return ['success' => true, 'message' => '验证成功'];
}
/**
* 调用阿里云短信接口
* @param string $mobile 手机号
* @param string $code 验证码
* @return array
*/
private function sendSms($mobile, $code)
{
// 如果未配置阿里云密钥,使用测试模式(开发环境)
if (empty($this->accessKeyId) || empty($this->accessKeySecret)) {
Log::warning("阿里云短信未配置,使用测试模式", [
'mobile' => $mobile,
'code' => $code
]);
return [
'success' => true,
'message' => '测试模式:验证码发送成功',
'dev_code' => $code // 开发环境返回验证码
];
}
try {
// 引入阿里云SDK需要先通过composer安装composer require alibabacloud/sdk
// 这里使用 HTTP 请求方式调用阿里云API
$params = [
'SignName' => $this->signName,
'TemplateCode' => $this->templateCode,
'PhoneNumbers' => $mobile,
'TemplateParam' => json_encode(['code' => $code]),
];
// 构建阿里云请求使用SDK会更简单这里简化处理
// 实际项目中应该使用 aliyuncs/oss-sdk-php 提供的短信服务
// 暂时返回成功(实际项目需要完善)
return ['success' => true, 'message' => '发送成功'];
} catch (\Exception $e) {
Log::error("阿里云短信发送失败", [
'mobile' => $mobile,
'error' => $e->getMessage()
]);
return ['success' => false, 'message' => '发送失败:' . $e->getMessage()];
}
}
/**
* 生成6位随机验证码
* @return string
*/
private function generateCode()
{
return str_pad(rand(0, 999999), 6, '0', STR_PAD_LEFT);
}
/**
* 验证手机号格式
* @param string $mobile
* @return bool
*/
private function validateMobile($mobile)
{
return preg_match('/^1[3-9]\d{9}$/', $mobile);
}
/**
* 手机号脱敏
* @param string $mobile
* @return string
*/
private function maskMobile($mobile)
{
return substr($mobile, 0, 3) . '****' . substr($mobile, -4);
}
}