This commit is contained in:
youda 2025-06-03 00:11:04 +08:00
parent 267a896532
commit e952ade2be
5 changed files with 274 additions and 2 deletions

View File

@ -0,0 +1,29 @@
<?php
namespace app\admin\controller;
use app\common\model\UserVerificationCode;
use think\facade\Request;
use think\facade\View;
class VerificationCode extends Base
{
/**
* 验证码列表
*/
public function index()
{
$account = input('account', '', 'trim');
$where = [];
if ($account) {
$where[] = ['account', 'like', "%$account%"];
}
$list = UserVerificationCode::where($where)
->order('id', 'desc')
->paginate([ 'query' => request()->param() ]);
View::assign([
'list' => $list,
'account' => $account,
]);
return View::fetch('VerificationCode/index');
}
}

View File

@ -479,4 +479,9 @@ Route::rule('diamond_edit', 'Diamond/edit', 'GET|POST');
Route::rule('diamond_del', 'Diamond/del', 'GET|POST');
Route::rule('diamond_status', 'Diamond/status', 'POST');
Route::rule('diamond_get_max_sort', 'Diamond/get_max_sort', 'GET');
#============================
#VerificationCode.php 验证码管理
#============================
Route::rule('verification_code', 'VerificationCode/index', 'GET|POST');

View File

@ -0,0 +1,55 @@
{include file="Public:header3" /}
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-body">
<!-- 搜索条件 -->
<div id="verification-code-list-body">
<form class="layui-form layui-form-pane" method="get" action="">
<div class="layui-form-item">
<div class="layui-inline">
<div class="layui-input-inline" style="width: 200px;">
<input type="text" name="account" value="{$account}" placeholder="手机号" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<button class="layui-btn" lay-submit lay-filter="search-verification-code">
<i class="layui-icon layui-icon-search"></i> 查询
</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<!-- 数据表格 -->
<table class="layui-table">
<thead>
<tr>
<th>ID</th>
<th>手机号</th>
<th>验证码</th>
<th>IP地址</th>
<th>发送时间</th>
<th>过期时间</th>
</tr>
</thead>
<tbody>
{volist name="list" id="item"}
<tr>
<td>{$item.id}</td>
<td>{$item.account}</td>
<td>{$item.code}</td>
<td>{$item.ip_address}</td>
<td>{$item.created_at}</td>
<td>{$item.expired_at}</td>
</tr>
{/volist}
</tbody>
</table>
<div class="pages">{$list|raw}</div>
</div>
</div>
</div>
{include file="Public:footer3" /}

View File

@ -0,0 +1,177 @@
<?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();
}
}

View File

@ -36,9 +36,15 @@ return [
'url' => '/admin/sign_config',
'name' => '用户签到设置',
],
// [
// 'url' => '/admin/user_loginStat',
// 'name' => '用户登录统计',
// ],
//验证码
[
'url' => '/admin/user_loginStat',
'name' => '用户登录统计',
'url' => '/admin/verification_code',
'name' => '验证码列表',
],
],
],