主题
短信发送
数据结构
后台短信发送功能提供了两个表,一个短信模板表,一个存储验证码的表,结构如下
短信模板表
sql
CREATE TABLE `system_sms_template` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`identify` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '模版唯一标识',
`channel` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'aliyun' COMMENT 'aliyun:阿里云短信,qcloud:腾讯短信',
`template_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '模版ID',
`content` varchar(2000) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '模版内容',
`variables` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '模版变量',
`creator_id` int unsigned NOT NULL DEFAULT '0' COMMENT '创建人ID',
`created_at` int unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`updated_at` int unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
`deleted_at` int unsigned NOT NULL DEFAULT '0' COMMENT '软删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='短信模版';
短信验证码表
sql
CREATE TABLE `system_sms_code` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`mobile` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '手机号',
`code` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '短信验证码',
`behavior` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '短信行为表: 1 login 2 register',
`channel` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'aliyun' COMMENT 'aliyun:阿里云短信,qcloud:腾讯短信',
`status` int NOT NULL DEFAULT '1' COMMENT '状态 1 未使用 2 已使用',
`expired_at` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '过期时间',
`created_at` int unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`updated_at` int unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='短信验证码记录';
配置
到后台系统管理->短信配置
里设置平台,目前支持阿里云
和腾讯云
两个平台,如下图配置对应的平台配置
然后配置对应平台的短信模板
WARNING
注意这里需要你先到平台配置对应的模板,需要等模板审核通过后,录入到后台
模板标识
字符串,这里的示例是login
模板ID
平台获取的模板 ID
使用
WARNING
确保已经配置好了模板和平台
使用起来很简单,例如项目是发送登录短信码
php
$smsCode = new SmsCode();
$smsCode->login($request->get('mobile'));
具体细节看如下代码
php
class SmsCode
{
protected Sms $channel;
public const LOGIN_BEHAVIOR = 'login';
public const REGISTER_BEHAVIOR = 'register';
public function __construct()
{
$this->channel = Factory::make();
}
/**
* 发送登录验证码
* @throws \Throwable
*/
public function login(string $mobile): bool
{
try {
// 使用存储短信验证码的模型
$smsCodeModel = new SystemSmsCode;
// 短信对应的手机号是否有验证码记录,如果验证码没有使用则返回错误
if ($smsCodeModel->hasCode($mobile, self::LOGIN_BEHAVIOR)) {
throw new FailedException('验证码未使用或者未过期');
}
// 生成新的验证码
$code = $this->getCode();
// 发送验证码
// self::LOGIN_BEHAVIOR 就是模板标识,是 login,用来查找模板,模板变量使用{}包裹,形如{code}
// [$code] 这个就是变量数组,里面的值会被系统依次解析,注意需要和模板变量一一对应
$this->channel->send(self::LOGIN_BEHAVIOR, $mobile, [$code]);
// 然后保存发送的手机号验证码
$smsCodeModel->store($mobile, self::LOGIN_BEHAVIOR, $code);
return true;
} catch (NoGatewayAvailableException $exception) {
throw new FailedException($exception->getLastException()->getMessage());
} catch (\Throwable|\Exception $e) {
throw new FailedException($e->getMessage());
}
}
/**
* @return void
*/
public function register(string $mobile)
{
$smsCodeModel = new SystemSmsCode;
$smsCodeModel->hasCode($mobile, 'register');
}
protected function getCode(): int
{
return rand(100000, 999999);
}
}