mirror of
https://devops.lemonos.cn/lawson/FendxPHP.git
synced 2026-06-15 15:02:49 +08:00
- 创建用户表(users)包含基本信息和认证字段 - 创建角色表(roles)用于权限控制 - 创建权限表(permissions)定义系统权限 - 创建用户角色关联表(user_roles)建立用户与角色关系 - 创建角色权限关联表(role_permissions)建立角色与权限关系 - 创建迁移记录表(migrations)追踪数据库变更 - 添加AdminController提供管理员面板功能 - 实现系统监控、配置管理、缓存清理等功能 - 添加AOP切面编程支持的各种通知类型 - 实现告警管理AlertManager支持多渠道告警 - 添加文档注解接口规范
304 lines
8.7 KiB
PHP
304 lines
8.7 KiB
PHP
<?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;
|
||
}
|
||
}
|