Files
FendxPHP/app/Validate/UserValidator.php
Lawson 2782d765fb feat(database): 添加用户角色权限系统及相关监控功能
- 创建用户表(users)包含基本信息和认证字段
- 创建角色表(roles)用于权限控制
- 创建权限表(permissions)定义系统权限
- 创建用户角色关联表(user_roles)建立用户与角色关系
- 创建角色权限关联表(role_permissions)建立角色与权限关系
- 创建迁移记录表(migrations)追踪数据库变更
- 添加AdminController提供管理员面板功能
- 实现系统监控、配置管理、缓存清理等功能
- 添加AOP切面编程支持的各种通知类型
- 实现告警管理AlertManager支持多渠道告警
- 添加文档注解接口规范
2026-04-08 17:00:28 +08:00

304 lines
8.7 KiB
PHP
Raw Permalink 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
declare(strict_types=1);
namespace App\Validate;
use Fendx\Web\Request\Request;
/**
* 用户验证器
*/
class UserValidator
{
/**
* 注册验证规则
*/
public function getRegisterRules(): array
{
return [
'username' => [
'required' => true,
'min' => 2,
'max' => 50,
'pattern' => '/^[a-zA-Z0-9_]+$/',
'message' => '用户名必填2-50位只能包含字母、数字、下划线'
],
'email' => [
'required' => true,
'max' => 100,
'pattern' => '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/',
'message' => '邮箱格式不正确'
],
'password' => [
'required' => true,
'min' => 6,
'max' => 255,
'pattern' => '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d@$!%*?&]{6,}$/',
'message' => '密码至少6位必须包含大小写字母和数字'
],
'nickname' => [
'required' => false,
'max' => 100,
'message' => '昵称最多100位'
],
'phone' => [
'required' => false,
'pattern' => '/^1[3-9]\d{9}$/',
'message' => '手机号格式不正确'
]
];
}
/**
* 登录验证规则
*/
public function getLoginRules(): array
{
return [
'username' => [
'required' => true,
'message' => '用户名必填'
],
'password' => [
'required' => true,
'message' => '密码必填'
]
];
}
/**
* 更新验证规则
*/
public function getUpdateRules(): array
{
return [
'nickname' => [
'required' => false,
'max' => 100,
'message' => '昵称最多100位'
],
'phone' => [
'required' => false,
'pattern' => '/^1[3-9]\d{9}$/',
'message' => '手机号格式不正确'
],
'avatar' => [
'required' => false,
'max' => 255,
'message' => '头像URL最多255位'
]
];
}
/**
* 密码修改验证规则
*/
public function getPasswordRules(): array
{
return [
'old_password' => [
'required' => true,
'message' => '原密码必填'
],
'new_password' => [
'required' => true,
'min' => 6,
'max' => 255,
'pattern' => '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d@$!%*?&]{6,}$/',
'message' => '新密码至少6位必须包含大小写字母和数字'
],
'confirm_password' => [
'required' => true,
'message' => '确认密码必填'
]
];
}
/**
* 验证注册数据
*/
public function validateRegister(Request $request): array
{
return $this->validate($request->all(), $this->getRegisterRules());
}
/**
* 验证登录数据
*/
public function validateLogin(Request $request): array
{
return $this->validate($request->all(), $this->getLoginRules());
}
/**
* 验证更新数据
*/
public function validateUpdate(Request $request): array
{
return $this->validate($request->all(), $this->getUpdateRules());
}
/**
* 验证密码修改数据
*/
public function validatePassword(Request $request): array
{
$data = $request->all();
$errors = $this->validate($data, $this->getPasswordRules());
// 验证确认密码
if (!isset($errors['new_password']) && !isset($errors['confirm_password'])) {
if ($data['new_password'] !== $data['confirm_password']) {
$errors['confirm_password'] = '两次输入的密码不一致';
}
}
return $errors;
}
/**
* 通用验证方法
*/
private function validate(array $data, array $rules): array
{
$errors = [];
foreach ($rules as $field => $rule) {
$value = $data[$field] ?? null;
// 必填验证
if ($rule['required'] && ($value === null || $value === '')) {
$errors[$field] = $rule['message'] ?? "字段 {$field} 必填";
continue;
}
// 如果字段不是必填且为空,跳过其他验证
if (!$rule['required'] && ($value === null || $value === '')) {
continue;
}
// 最小长度验证
if (isset($rule['min']) && strlen($value) < $rule['min']) {
$errors[$field] = $rule['message'] ?? "字段 {$field} 长度不能少于 {$rule['min']}";
}
// 最大长度验证
if (isset($rule['max']) && strlen($value) > $rule['max']) {
$errors[$field] = $rule['message'] ?? "字段 {$field} 长度不能超过 {$rule['max']}";
}
// 正则表达式验证
if (isset($rule['pattern']) && !preg_match($rule['pattern'], $value)) {
$errors[$field] = $rule['message'] ?? "字段 {$field} 格式不正确";
}
// 自定义验证方法
if (isset($rule['custom']) && is_callable($rule['custom'])) {
$customError = $rule['custom']($value, $data);
if ($customError) {
$errors[$field] = $customError;
}
}
}
return $errors;
}
/**
* 验证用户名唯一性
*/
public function validateUniqueUsername(string $username, ?int $excludeId = null): ?string
{
// 这里应该调用UserService检查用户名唯一性
// $userService = app(UserService::class);
// if ($userService->existsByUsername($username, $excludeId)) {
// return '用户名已存在';
// }
return null;
}
/**
* 验证邮箱唯一性
*/
public function validateUniqueEmail(string $email, ?int $excludeId = null): ?string
{
// 这里应该调用UserService检查邮箱唯一性
// $userService = app(UserService::class);
// if ($userService->existsByEmail($email, $excludeId)) {
// return '邮箱已存在';
// }
return null;
}
/**
* 验证手机号唯一性
*/
public function validateUniquePhone(string $phone, ?int $excludeId = null): ?string
{
if (empty($phone)) {
return null;
}
// 这里应该调用UserService检查手机号唯一性
// $userService = app(UserService::class);
// if ($userService->existsByPhone($phone, $excludeId)) {
// return '手机号已存在';
// }
return null;
}
/**
* 完整的注册验证(包含唯一性检查)
*/
public function validateRegisterFull(Request $request): array
{
$data = $request->all();
$errors = $this->validateRegister($request);
if (empty($errors)) {
// 检查用户名唯一性
$usernameError = $this->validateUniqueUsername($data['username']);
if ($usernameError) {
$errors['username'] = $usernameError;
}
// 检查邮箱唯一性
$emailError = $this->validateUniqueEmail($data['email']);
if ($emailError) {
$errors['email'] = $emailError;
}
// 检查手机号唯一性(如果提供)
if (!empty($data['phone'])) {
$phoneError = $this->validateUniquePhone($data['phone']);
if ($phoneError) {
$errors['phone'] = $phoneError;
}
}
}
return $errors;
}
/**
* 完整的更新验证(包含唯一性检查)
*/
public function validateUpdateFull(Request $request, int $userId): array
{
$data = $request->all();
$errors = $this->validateUpdate($request);
if (empty($errors)) {
// 检查手机号唯一性(如果提供)
if (!empty($data['phone'])) {
$phoneError = $this->validateUniquePhone($data['phone'], $userId);
if ($phoneError) {
$errors['phone'] = $phoneError;
}
}
}
return $errors;
}
}