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:
440
app/Dto/CollectionDto.php
Normal file
440
app/Dto/CollectionDto.php
Normal file
@@ -0,0 +1,440 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
/**
|
||||
* 数据集合传输对象
|
||||
*/
|
||||
class CollectionDto extends BaseDto
|
||||
{
|
||||
private array $items = [];
|
||||
|
||||
private int $count = 0;
|
||||
|
||||
private array $meta = [];
|
||||
|
||||
public function __construct(array $items = [])
|
||||
{
|
||||
$this->items = $items;
|
||||
$this->count = count($items);
|
||||
}
|
||||
|
||||
public function getItems(): array
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
public function setItems(array $items): self
|
||||
{
|
||||
$this->items = $items;
|
||||
$this->count = count($items);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCount(): int
|
||||
{
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
public function getMeta(): array
|
||||
{
|
||||
return $this->meta;
|
||||
}
|
||||
|
||||
public function setMeta(array $meta): self
|
||||
{
|
||||
$this->meta = $meta;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加项目
|
||||
*/
|
||||
public function add(mixed $item): self
|
||||
{
|
||||
$this->items[] = $item;
|
||||
$this->count++;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加元数据
|
||||
*/
|
||||
public function addMeta(string $key, mixed $value): self
|
||||
{
|
||||
$this->meta[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否为空
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return $this->count === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否不为空
|
||||
*/
|
||||
public function isNotEmpty(): bool
|
||||
{
|
||||
return $this->count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取第一个项目
|
||||
*/
|
||||
public function first(): mixed
|
||||
{
|
||||
return $this->items[0] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最后一个项目
|
||||
*/
|
||||
public function last(): mixed
|
||||
{
|
||||
return $this->items[$this->count - 1] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定索引的项目
|
||||
*/
|
||||
public function get(int $index): mixed
|
||||
{
|
||||
return $this->items[$index] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 映射集合
|
||||
*/
|
||||
public function map(callable $callback): self
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->items = array_map($callback, $this->items);
|
||||
return $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤集合
|
||||
*/
|
||||
public function filter(callable $callback): self
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->items = array_filter($this->items, $callback);
|
||||
$new->count = count($new->items);
|
||||
return $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* 排序集合
|
||||
*/
|
||||
public function sort(callable $callback): self
|
||||
{
|
||||
$new = clone $this;
|
||||
$items = $this->items;
|
||||
usort($items, $callback);
|
||||
$new->items = $items;
|
||||
return $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* 反转集合
|
||||
*/
|
||||
public function reverse(): self
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->items = array_reverse($this->items);
|
||||
return $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取唯一的集合
|
||||
*/
|
||||
public function unique(): self
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->items = array_unique($this->items);
|
||||
$new->count = count($new->items);
|
||||
return $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切片集合
|
||||
*/
|
||||
public function slice(int $offset, ?int $length = null): self
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->items = array_slice($this->items, $offset, $length);
|
||||
$new->count = count($new->items);
|
||||
return $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* 限制集合大小
|
||||
*/
|
||||
public function take(int $limit): self
|
||||
{
|
||||
return $this->slice(0, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳过指定数量
|
||||
*/
|
||||
public function skip(int $count): self
|
||||
{
|
||||
return $this->slice($count);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分块集合
|
||||
*/
|
||||
public function chunk(int $size): array
|
||||
{
|
||||
return array_chunk($this->items, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 求和
|
||||
*/
|
||||
public function sum(callable|string $key = null): float
|
||||
{
|
||||
if ($key === null) {
|
||||
return array_sum($this->items);
|
||||
}
|
||||
|
||||
if (is_callable($key)) {
|
||||
return array_sum(array_map($key, $this->items));
|
||||
}
|
||||
|
||||
return array_sum(array_column($this->items, $key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 求平均值
|
||||
*/
|
||||
public function avg(callable|string $key = null): float
|
||||
{
|
||||
if ($this->isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->sum($key) / $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 求最大值
|
||||
*/
|
||||
public function max(callable|string $key = null): mixed
|
||||
{
|
||||
if ($this->isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($key === null) {
|
||||
return max($this->items);
|
||||
}
|
||||
|
||||
if (is_callable($key)) {
|
||||
$values = array_map($key, $this->items);
|
||||
return max($values);
|
||||
}
|
||||
|
||||
return max(array_column($this->items, $key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 求最小值
|
||||
*/
|
||||
public function min(callable|string $key = null): mixed
|
||||
{
|
||||
if ($this->isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($key === null) {
|
||||
return min($this->items);
|
||||
}
|
||||
|
||||
if (is_callable($key)) {
|
||||
$values = array_map($key, $this->items);
|
||||
return min($values);
|
||||
}
|
||||
|
||||
return min(array_column($this->items, $key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找项目
|
||||
*/
|
||||
public function find(callable $callback): mixed
|
||||
{
|
||||
foreach ($this->items as $item) {
|
||||
if ($callback($item)) {
|
||||
return $item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否存在项目
|
||||
*/
|
||||
public function contains(mixed $item): bool
|
||||
{
|
||||
return in_array($item, $this->items, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否包含满足条件的项目
|
||||
*/
|
||||
public function containsWhere(callable $callback): bool
|
||||
{
|
||||
return $this->find($callback) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有键
|
||||
*/
|
||||
public function keys(): array
|
||||
{
|
||||
return array_keys($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有值
|
||||
*/
|
||||
public function values(): array
|
||||
{
|
||||
return array_values($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并其他集合
|
||||
*/
|
||||
public function merge(self $other): self
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->items = array_merge($this->items, $other->getItems());
|
||||
$new->count = count($new->items);
|
||||
return $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为分页对象
|
||||
*/
|
||||
public function toPagination(int $page = 1, int $pageSize = 10): PaginationDto
|
||||
{
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$items = array_slice($this->items, $offset, $pageSize);
|
||||
|
||||
return PaginationDto::create($items, $this->count, $page, $pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建空集合
|
||||
*/
|
||||
public static function empty(): self
|
||||
{
|
||||
return new self([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数组创建集合
|
||||
*/
|
||||
public static function fromArray(array $items): self
|
||||
{
|
||||
return new self($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建包含单个项目的集合
|
||||
*/
|
||||
public static function of(mixed $item): self
|
||||
{
|
||||
return new self([$item]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建范围集合
|
||||
*/
|
||||
public static function range(int $start, int $end): self
|
||||
{
|
||||
return new self(range($start, $end));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为数组
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'items' => $this->items,
|
||||
'count' => $this->count,
|
||||
'meta' => empty($this->meta) ? null : $this->meta,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为JSON
|
||||
*/
|
||||
public function toJson(): string
|
||||
{
|
||||
return json_encode($this->toArray(), JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现ArrayAccess接口
|
||||
*/
|
||||
public function offsetExists(mixed $offset): bool
|
||||
{
|
||||
return isset($this->items[$offset]);
|
||||
}
|
||||
|
||||
public function offsetGet(mixed $offset): mixed
|
||||
{
|
||||
return $this->items[$offset] ?? null;
|
||||
}
|
||||
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
if ($offset === null) {
|
||||
$this->items[] = $value;
|
||||
} else {
|
||||
$this->items[$offset] = $value;
|
||||
}
|
||||
$this->count = count($this->items);
|
||||
}
|
||||
|
||||
public function offsetUnset(mixed $offset): void
|
||||
{
|
||||
unset($this->items[$offset]);
|
||||
$this->count = count($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现Countable接口
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现IteratorAggregate接口
|
||||
*/
|
||||
public function getIterator(): \ArrayIterator
|
||||
{
|
||||
return new \ArrayIterator($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现JsonSerializable接口
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user