From e952ade2be86571cc2abe9d6fdb44b0921f08a1f Mon Sep 17 00:00:00 2001 From: youda Date: Tue, 3 Jun 2025 00:11:04 +0800 Subject: [PATCH] 333 --- app/admin/controller/VerificationCode.php | 29 ++++ app/admin/route/app.php | 5 + app/admin/view/VerificationCode/index.html | 55 +++++++ app/common/model/UserVerificationCode.php | 177 +++++++++++++++++++++ config/menu.php | 10 +- 5 files changed, 274 insertions(+), 2 deletions(-) create mode 100644 app/admin/controller/VerificationCode.php create mode 100644 app/admin/view/VerificationCode/index.html create mode 100644 app/common/model/UserVerificationCode.php diff --git a/app/admin/controller/VerificationCode.php b/app/admin/controller/VerificationCode.php new file mode 100644 index 0000000..7533305 --- /dev/null +++ b/app/admin/controller/VerificationCode.php @@ -0,0 +1,29 @@ +order('id', 'desc') + ->paginate([ 'query' => request()->param() ]); + View::assign([ + 'list' => $list, + 'account' => $account, + ]); + return View::fetch('VerificationCode/index'); + } +} \ No newline at end of file diff --git a/app/admin/route/app.php b/app/admin/route/app.php index da1fa99..4b4952b 100755 --- a/app/admin/route/app.php +++ b/app/admin/route/app.php @@ -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'); \ No newline at end of file diff --git a/app/admin/view/VerificationCode/index.html b/app/admin/view/VerificationCode/index.html new file mode 100644 index 0000000..b5b8b3a --- /dev/null +++ b/app/admin/view/VerificationCode/index.html @@ -0,0 +1,55 @@ +{include file="Public:header3" /} + +
+
+
+ +
+
+
+
+
+ +
+
+
+ + +
+
+
+
+ + + + + + + + + + + + + + + {volist name="list" id="item"} + + + + + + + + + {/volist} + +
ID手机号验证码IP地址发送时间过期时间
{$item.id}{$item.account}{$item.code}{$item.ip_address}{$item.created_at}{$item.expired_at}
+
{$list|raw}
+
+
+
+ +{include file="Public:footer3" /} \ No newline at end of file diff --git a/app/common/model/UserVerificationCode.php b/app/common/model/UserVerificationCode.php new file mode 100644 index 0000000..818d39b --- /dev/null +++ b/app/common/model/UserVerificationCode.php @@ -0,0 +1,177 @@ + '注册', + 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(); + } +} \ No newline at end of file diff --git a/config/menu.php b/config/menu.php index 0adaefa..8a7c6b0 100755 --- a/config/menu.php +++ b/config/menu.php @@ -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' => '验证码列表', ], ], ],