177 lines
4.8 KiB
PHP
177 lines
4.8 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace app\common\model;
|
|
|
|
use think\Model;
|
|
|
|
class UserVerificationCode extends Model
|
|
{
|
|
// 设置表名
|
|
protected $name = 'user_verification_codes';
|
|
|
|
// 设置主键
|
|
protected $pk = 'id';
|
|
|
|
// 自动写入时间戳
|
|
protected $autoWriteTimestamp = true;
|
|
|
|
// 定义时间戳字段名
|
|
protected $createTime = 'created_at';
|
|
protected $updateTime = 'updated_at';
|
|
|
|
// 验证码类型常量
|
|
const TYPE_REGISTER = 1; // 注册
|
|
const TYPE_LOGIN = 2; // 登录
|
|
const TYPE_RESET_PASSWORD = 3; // 找回密码
|
|
const TYPE_CHANGE_MOBILE = 4; // 修改手机
|
|
const TYPE_CHANGE_EMAIL = 5; // 修改邮箱
|
|
const TYPE_OTHER = 6; // 其他
|
|
|
|
// 状态常量
|
|
const STATUS_UNUSED = 0; // 未使用
|
|
const STATUS_USED = 1; // 已使用
|
|
const STATUS_EXPIRED = 2; // 已失效
|
|
|
|
// 发送渠道常量
|
|
const CHANNEL_SMS = 'sms'; // 短信
|
|
const CHANNEL_EMAIL = 'email'; // 邮件
|
|
|
|
/**
|
|
* 获取验证码类型列表
|
|
* @return array
|
|
*/
|
|
public static function getCodeTypes(): array
|
|
{
|
|
return [
|
|
self::TYPE_REGISTER => '注册',
|
|
self::TYPE_LOGIN => '登录',
|
|
self::TYPE_RESET_PASSWORD => '找回密码',
|
|
self::TYPE_CHANGE_MOBILE => '修改手机',
|
|
self::TYPE_CHANGE_EMAIL => '修改邮箱',
|
|
self::TYPE_OTHER => '其他'
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 获取状态列表
|
|
* @return array
|
|
*/
|
|
public static function getStatusList(): array
|
|
{
|
|
return [
|
|
self::STATUS_UNUSED => '未使用',
|
|
self::STATUS_USED => '已使用',
|
|
self::STATUS_EXPIRED => '已失效'
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 获取发送渠道列表
|
|
* @return array
|
|
*/
|
|
public static function getChannelList(): array
|
|
{
|
|
return [
|
|
self::CHANNEL_SMS => '短信',
|
|
self::CHANNEL_EMAIL => '邮件'
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 创建验证码
|
|
* @param string $account 账号
|
|
* @param string $code 验证码
|
|
* @param int $codeType 验证码类型
|
|
* @param string $channel 发送渠道
|
|
* @param string $ipAddress IP地址
|
|
* @param int $userId 用户ID
|
|
* @param int $expireMinutes 过期时间(分钟)
|
|
* @return UserVerificationCode
|
|
*/
|
|
public static function createCode(
|
|
string $account,
|
|
string $code,
|
|
int $codeType,
|
|
string $channel,
|
|
string $ipAddress = '',
|
|
int $userId = 0,
|
|
int $expireMinutes = 5
|
|
): self {
|
|
$data = [
|
|
'user_id' => $userId,
|
|
'account' => $account,
|
|
'code' => $code,
|
|
'code_type' => $codeType,
|
|
'channel' => $channel,
|
|
'ip_address' => $ipAddress,
|
|
'status' => self::STATUS_UNUSED,
|
|
'expired_at' => date('Y-m-d H:i:s', time() + $expireMinutes * 60)
|
|
];
|
|
|
|
return self::create($data);
|
|
}
|
|
|
|
/**
|
|
* 验证验证码
|
|
* @param string $account 账号
|
|
* @param string $code 验证码
|
|
* @param int $codeType 验证码类型
|
|
* @return bool
|
|
*/
|
|
public static function verifyCode(string $account, string $code, int $codeType): bool
|
|
{
|
|
$verificationCode = self::where([
|
|
'account' => $account,
|
|
'code' => $code,
|
|
'code_type' => $codeType,
|
|
'status' => self::STATUS_UNUSED
|
|
])
|
|
->where('expired_at', '>', date('Y-m-d H:i:s'))
|
|
->find();
|
|
|
|
if (!$verificationCode) {
|
|
return false;
|
|
}
|
|
|
|
// 更新验证码状态
|
|
$verificationCode->status = self::STATUS_USED;
|
|
$verificationCode->used_at = date('Y-m-d H:i:s');
|
|
return $verificationCode->save();
|
|
}
|
|
|
|
/**
|
|
* 使验证码失效
|
|
* @param string $account 账号
|
|
* @param int $codeType 验证码类型
|
|
* @return bool
|
|
*/
|
|
public static function invalidateCode(string $account, int $codeType): bool
|
|
{
|
|
return self::where([
|
|
'account' => $account,
|
|
'code_type' => $codeType,
|
|
'status' => self::STATUS_UNUSED
|
|
])->update([
|
|
'status' => self::STATUS_EXPIRED
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 获取最近的验证码
|
|
* @param string $account 账号
|
|
* @param int $codeType 验证码类型
|
|
* @return UserVerificationCode|null
|
|
*/
|
|
public static function getLatestCode(string $account, int $codeType): ?self
|
|
{
|
|
return self::where([
|
|
'account' => $account,
|
|
'code_type' => $codeType,
|
|
'status' => self::STATUS_UNUSED
|
|
])
|
|
->where('expired_at', '>', date('Y-m-d H:i:s'))
|
|
->order('id', 'desc')
|
|
->find();
|
|
}
|
|
}
|