mirror of
https://devops.lemonos.cn/lawson/FendxPHP.git
synced 2026-06-15 23:12:49 +08:00
feat(database): 添加用户角色权限系统及相关监控功能
- 创建用户表(users)包含基本信息和认证字段 - 创建角色表(roles)用于权限控制 - 创建权限表(permissions)定义系统权限 - 创建用户角色关联表(user_roles)建立用户与角色关系 - 创建角色权限关联表(role_permissions)建立角色与权限关系 - 创建迁移记录表(migrations)追踪数据库变更 - 添加AdminController提供管理员面板功能 - 实现系统监控、配置管理、缓存清理等功能 - 添加AOP切面编程支持的各种通知类型 - 实现告警管理AlertManager支持多渠道告警 - 添加文档注解接口规范
This commit is contained in:
426
app/Validate/BaseValidator.php
Normal file
426
app/Validate/BaseValidator.php
Normal file
@@ -0,0 +1,426 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Validate;
|
||||
|
||||
use Fendx\Web\Request\Request;
|
||||
|
||||
/**
|
||||
* 验证器基类
|
||||
*/
|
||||
abstract class BaseValidator
|
||||
{
|
||||
/**
|
||||
* 验证规则
|
||||
*/
|
||||
abstract protected function getRules(): array;
|
||||
|
||||
/**
|
||||
* 验证请求数据
|
||||
*/
|
||||
public function validate(Request $request): array
|
||||
{
|
||||
return $this->validateData($request->all(), $this->getRules());
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证数组数据
|
||||
*/
|
||||
public function validateData(array $data, array $rules): array
|
||||
{
|
||||
$errors = [];
|
||||
|
||||
foreach ($rules as $field => $rule) {
|
||||
$value = $data[$field] ?? null;
|
||||
$fieldErrors = $this->validateField($field, $value, $rule, $data);
|
||||
|
||||
if (!empty($fieldErrors)) {
|
||||
$errors[$field] = $fieldErrors;
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证单个字段
|
||||
*/
|
||||
protected function validateField(string $field, mixed $value, array $rule, array $data): array
|
||||
{
|
||||
$errors = [];
|
||||
|
||||
// 必填验证
|
||||
if ($rule['required'] && ($value === null || $value === '')) {
|
||||
$errors[] = $rule['message'] ?? "字段 {$field} 必填";
|
||||
return $errors;
|
||||
}
|
||||
|
||||
// 如果字段不是必填且为空,跳过其他验证
|
||||
if (!$rule['required'] && ($value === null || $value === '')) {
|
||||
return $errors;
|
||||
}
|
||||
|
||||
// 类型验证
|
||||
if (isset($rule['type'])) {
|
||||
$typeError = $this->validateType($field, $value, $rule['type']);
|
||||
if ($typeError) {
|
||||
$errors[] = $typeError;
|
||||
}
|
||||
}
|
||||
|
||||
// 长度验证
|
||||
if (isset($rule['min'])) {
|
||||
$minError = $this->validateMin($field, $value, $rule['min']);
|
||||
if ($minError) {
|
||||
$errors[] = $minError;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($rule['max'])) {
|
||||
$maxError = $this->validateMax($field, $value, $rule['max']);
|
||||
if ($maxError) {
|
||||
$errors[] = $maxError;
|
||||
}
|
||||
}
|
||||
|
||||
// 数值范围验证
|
||||
if (isset($rule['min_value'])) {
|
||||
$minValueError = $this->validateMinValue($field, $value, $rule['min_value']);
|
||||
if ($minValueError) {
|
||||
$errors[] = $minValueError;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($rule['max_value'])) {
|
||||
$maxValueError = $this->validateMaxValue($field, $value, $rule['max_value']);
|
||||
if ($maxValueError) {
|
||||
$errors[] = $maxValueError;
|
||||
}
|
||||
}
|
||||
|
||||
// 正则表达式验证
|
||||
if (isset($rule['pattern'])) {
|
||||
$patternError = $this->validatePattern($field, $value, $rule['pattern']);
|
||||
if ($patternError) {
|
||||
$errors[] = $patternError;
|
||||
}
|
||||
}
|
||||
|
||||
// 枚举值验证
|
||||
if (isset($rule['enum'])) {
|
||||
$enumError = $this->validateEnum($field, $value, $rule['enum']);
|
||||
if ($enumError) {
|
||||
$errors[] = $enumError;
|
||||
}
|
||||
}
|
||||
|
||||
// 邮箱验证
|
||||
if (isset($rule['email']) && $rule['email']) {
|
||||
$emailError = $this->validateEmail($field, $value);
|
||||
if ($emailError) {
|
||||
$errors[] = $emailError;
|
||||
}
|
||||
}
|
||||
|
||||
// URL验证
|
||||
if (isset($rule['url']) && $rule['url']) {
|
||||
$urlError = $this->validateUrl($field, $value);
|
||||
if ($urlError) {
|
||||
$errors[] = $urlError;
|
||||
}
|
||||
}
|
||||
|
||||
// 日期验证
|
||||
if (isset($rule['date']) && $rule['date']) {
|
||||
$dateError = $this->validateDate($field, $value, $rule['format'] ?? 'Y-m-d');
|
||||
if ($dateError) {
|
||||
$errors[] = $dateError;
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义验证
|
||||
if (isset($rule['custom']) && is_callable($rule['custom'])) {
|
||||
$customError = $rule['custom']($value, $data, $field);
|
||||
if ($customError) {
|
||||
$errors[] = $customError;
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* 类型验证
|
||||
*/
|
||||
protected function validateType(string $field, mixed $value, string $type): ?string
|
||||
{
|
||||
switch ($type) {
|
||||
case 'int':
|
||||
case 'integer':
|
||||
if (!is_int($value) && !ctype_digit((string)$value)) {
|
||||
return "字段 {$field} 必须是整数";
|
||||
}
|
||||
break;
|
||||
case 'float':
|
||||
case 'double':
|
||||
if (!is_float($value) && !is_numeric($value)) {
|
||||
return "字段 {$field} 必须是数字";
|
||||
}
|
||||
break;
|
||||
case 'string':
|
||||
if (!is_string($value)) {
|
||||
return "字段 {$field} 必须是字符串";
|
||||
}
|
||||
break;
|
||||
case 'bool':
|
||||
case 'boolean':
|
||||
if (!is_bool($value) && !in_array($value, [0, 1, '0', '1', 'true', 'false'])) {
|
||||
return "字段 {$field} 必须是布尔值";
|
||||
}
|
||||
break;
|
||||
case 'array':
|
||||
if (!is_array($value)) {
|
||||
return "字段 {$field} 必须是数组";
|
||||
}
|
||||
break;
|
||||
case 'date':
|
||||
if (!($value instanceof \DateTime) && !strtotime($value)) {
|
||||
return "字段 {$field} 必须是有效日期";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最小长度验证
|
||||
*/
|
||||
protected function validateMin(string $field, mixed $value, int $min): ?string
|
||||
{
|
||||
$length = is_array($value) ? count($value) : strlen((string)$value);
|
||||
if ($length < $min) {
|
||||
return "字段 {$field} 长度不能少于 {$min}";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最大长度验证
|
||||
*/
|
||||
protected function validateMax(string $field, mixed $value, int $max): ?string
|
||||
{
|
||||
$length = is_array($value) ? count($value) : strlen((string)$value);
|
||||
if ($length > $max) {
|
||||
return "字段 {$field} 长度不能超过 {$max}";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最小值验证
|
||||
*/
|
||||
protected function validateMinValue(string $field, mixed $value, int|float $min): ?string
|
||||
{
|
||||
if (!is_numeric($value) || $value < $min) {
|
||||
return "字段 {$field} 值不能小于 {$min}";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最大值验证
|
||||
*/
|
||||
protected function validateMaxValue(string $field, mixed $value, int|float $max): ?string
|
||||
{
|
||||
if (!is_numeric($value) || $value > $max) {
|
||||
return "字段 {$field} 值不能大于 {$max}";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 正则表达式验证
|
||||
*/
|
||||
protected function validatePattern(string $field, mixed $value, string $pattern): ?string
|
||||
{
|
||||
if (!preg_match($pattern, (string)$value)) {
|
||||
return "字段 {$field} 格式不正确";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 枚举值验证
|
||||
*/
|
||||
protected function validateEnum(string $field, mixed $value, array $enum): ?string
|
||||
{
|
||||
if (!in_array($value, $enum)) {
|
||||
return "字段 {$field} 值必须是: " . implode(', ', $enum);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 邮箱验证
|
||||
*/
|
||||
protected function validateEmail(string $field, mixed $value): ?string
|
||||
{
|
||||
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
|
||||
return "字段 {$field} 必须是有效邮箱地址";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* URL验证
|
||||
*/
|
||||
protected function validateUrl(string $field, mixed $value): ?string
|
||||
{
|
||||
if (!filter_var($value, FILTER_VALIDATE_URL)) {
|
||||
return "字段 {$field} 必须是有效URL";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期验证
|
||||
*/
|
||||
protected function validateDate(string $field, mixed $value, string $format): ?string
|
||||
{
|
||||
if ($value instanceof \DateTime) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$date = \DateTime::createFromFormat($format, $value);
|
||||
if (!$date || $date->format($format) !== $value) {
|
||||
return "字段 {$field} 必须是有效日期,格式: {$format}";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建验证规则
|
||||
*/
|
||||
protected function rule(string $type = 'string', bool $required = false): array
|
||||
{
|
||||
return [
|
||||
'type' => $type,
|
||||
'required' => $required
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加必填规则
|
||||
*/
|
||||
protected function required(string $message = null): array
|
||||
{
|
||||
return [
|
||||
'required' => true,
|
||||
'message' => $message
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加长度规则
|
||||
*/
|
||||
protected function length(int $min = null, int $max = null, string $message = null): array
|
||||
{
|
||||
$rule = [];
|
||||
if ($min !== null) {
|
||||
$rule['min'] = $min;
|
||||
}
|
||||
if ($max !== null) {
|
||||
$rule['max'] = $max;
|
||||
}
|
||||
if ($message) {
|
||||
$rule['message'] = $message;
|
||||
}
|
||||
return $rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加数值范围规则
|
||||
*/
|
||||
protected function range(int|float $min = null, int|float $max = null, string $message = null): array
|
||||
{
|
||||
$rule = [];
|
||||
if ($min !== null) {
|
||||
$rule['min_value'] = $min;
|
||||
}
|
||||
if ($max !== null) {
|
||||
$rule['max_value'] = $max;
|
||||
}
|
||||
if ($message) {
|
||||
$rule['message'] = $message;
|
||||
}
|
||||
return $rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加正则表达式规则
|
||||
*/
|
||||
protected function pattern(string $regex, string $message = null): array
|
||||
{
|
||||
return [
|
||||
'pattern' => $regex,
|
||||
'message' => $message ?? '格式不正确'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加枚举规则
|
||||
*/
|
||||
protected function enum(array $values, string $message = null): array
|
||||
{
|
||||
return [
|
||||
'enum' => $values,
|
||||
'message' => $message ?? '值必须在指定范围内'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加邮箱规则
|
||||
*/
|
||||
protected function email(string $message = null): array
|
||||
{
|
||||
return [
|
||||
'email' => true,
|
||||
'message' => $message ?? '必须是有效邮箱地址'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加URL规则
|
||||
*/
|
||||
protected function url(string $message = null): array
|
||||
{
|
||||
return [
|
||||
'url' => true,
|
||||
'message' => $message ?? '必须是有效URL'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加日期规则
|
||||
*/
|
||||
protected function date(string $format = 'Y-m-d', string $message = null): array
|
||||
{
|
||||
return [
|
||||
'date' => true,
|
||||
'format' => $format,
|
||||
'message' => $message ?? "必须是有效日期,格式: {$format}"
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加自定义验证规则
|
||||
*/
|
||||
protected function custom(callable $callback, string $message = null): array
|
||||
{
|
||||
return [
|
||||
'custom' => $callback,
|
||||
'message' => $message
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user