Files
FendxPHP/app/Vo/UserVo.php

457 lines
10 KiB
PHP
Raw Permalink Normal View History

<?php
declare(strict_types=1);
namespace App\Vo;
use App\Dto\UserDto;
/**
* 用户前端展示对象
*/
class UserVo
{
private ?int $id = null;
private string $username = '';
private string $email = '';
private string $nickname = '';
private string $phone = '';
private string $avatar = '';
private ?int $status = null;
private ?string $statusText = null;
private ?string $roleName = null;
private ?string $createdAt = null;
private ?string $updatedAt = null;
private ?string $lastLoginAt = null;
private array $permissions = [];
private array $roles = [];
private array $extra = [];
public function __construct(UserDto $userDto = null)
{
if ($userDto) {
$this->fromDto($userDto);
}
}
public function getId(): ?int
{
return $this->id;
}
public function setId(int $id): self
{
$this->id = $id;
return $this;
}
public function getUsername(): string
{
return $this->username;
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
public function getEmail(): string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getNickname(): string
{
return $this->nickname;
}
public function setNickname(string $nickname): self
{
$this->nickname = $nickname;
return $this;
}
public function getPhone(): string
{
return $this->phone;
}
public function setPhone(string $phone): self
{
$this->phone = $phone;
return $this;
}
public function getAvatar(): string
{
return $this->avatar;
}
public function setAvatar(string $avatar): self
{
$this->avatar = $avatar;
return $this;
}
public function getStatus(): ?int
{
return $this->status;
}
public function setStatus(int $status): self
{
$this->status = $status;
$this->statusText = $this->getStatusText($status);
return $this;
}
public function getStatusText(): ?string
{
return $this->statusText;
}
public function getRoleName(): ?string
{
return $this->roleName;
}
public function setRoleName(string $roleName): self
{
$this->roleName = $roleName;
return $this;
}
public function getCreatedAt(): ?string
{
return $this->createdAt;
}
public function setCreatedAt(string $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getUpdatedAt(): ?string
{
return $this->updatedAt;
}
public function setUpdatedAt(string $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getLastLoginAt(): ?string
{
return $this->lastLoginAt;
}
public function setLastLoginAt(string $lastLoginAt): self
{
$this->lastLoginAt = $lastLoginAt;
return $this;
}
public function getPermissions(): array
{
return $this->permissions;
}
public function setPermissions(array $permissions): self
{
$this->permissions = $permissions;
return $this;
}
public function getRoles(): array
{
return $this->roles;
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
public function getExtra(): array
{
return $this->extra;
}
public function setExtra(array $extra): self
{
$this->extra = $extra;
return $this;
}
/**
* 添加额外信息
*/
public function addExtra(string $key, mixed $value): self
{
$this->extra[$key] = $value;
return $this;
}
/**
* 从DTO转换
*/
public function fromDto(UserDto $dto): self
{
$this->id = $dto->getId();
$this->username = $dto->getUsername();
$this->email = $dto->getEmail();
$this->nickname = $dto->getNickname();
$this->phone = $dto->getPhone();
$this->avatar = $dto->getAvatar();
$this->status = $dto->getStatus();
$this->statusText = $this->getStatusText($this->status);
$this->roleName = $dto->getRoleName();
$this->permissions = $dto->getPermissions();
$this->roles = $dto->getRoles();
// 格式化日期
if ($dto->getCreatedAt()) {
$this->createdAt = $dto->getCreatedAt()->format('Y-m-d H:i:s');
}
if ($dto->getUpdatedAt()) {
$this->updatedAt = $dto->getUpdatedAt()->format('Y-m-d H:i:s');
}
if ($dto->getLastLoginAt()) {
$this->lastLoginAt = $dto->getLastLoginAt()->format('Y-m-d H:i:s');
}
return $this;
}
/**
* 获取状态文本
*/
private function getStatusText(int $status): string
{
return match ($status) {
1 => '正常',
2 => '禁用',
3 => '待审核',
0 => '删除',
default => '未知'
};
}
/**
* 获取显示名称(优先使用昵称)
*/
public function getDisplayName(): string
{
return !empty($this->nickname) ? $this->nickname : $this->username;
}
/**
* 获取头像URL默认头像
*/
public function getAvatarUrl(): string
{
if (!empty($this->avatar)) {
return $this->avatar;
}
// 默认头像
return 'https://via.placeholder.com/100x100?text=' . urlencode(substr($this->getDisplayName(), 0, 1));
}
/**
* 获取手机号显示格式隐藏中间4位
*/
public function getPhoneDisplay(): string
{
if (empty($this->phone)) {
return '';
}
return substr($this->phone, 0, 3) . '****' . substr($this->phone, -4);
}
/**
* 获取邮箱显示格式(隐藏部分字符)
*/
public function getEmailDisplay(): string
{
if (empty($this->email)) {
return '';
}
$parts = explode('@', $this->email);
if (count($parts) !== 2) {
return $this->email;
}
$username = $parts[0];
$domain = $parts[1];
if (strlen($username) <= 3) {
$maskedUsername = str_repeat('*', strlen($username));
} else {
$maskedUsername = substr($username, 0, 2) . str_repeat('*', strlen($username) - 2);
}
return $maskedUsername . '@' . $domain;
}
/**
* 检查是否在线
*/
public function isOnline(): bool
{
if (!$this->lastLoginAt) {
return false;
}
$lastLoginTime = strtotime($this->lastLoginAt);
$onlineThreshold = 30 * 60; // 30分钟内在线
return (time() - $lastLoginTime) < $onlineThreshold;
}
/**
* 检查是否活跃用户
*/
public function isActive(): bool
{
return $this->status === 1;
}
/**
* 获取用户标签
*/
public function getTags(): array
{
$tags = [];
if ($this->isActive()) {
$tags[] = ['text' => '正常', 'type' => 'success'];
} else {
$tags[] = ['text' => $this->statusText, 'type' => 'danger'];
}
if ($this->isOnline()) {
$tags[] = ['text' => '在线', 'type' => 'primary'];
}
if (!empty($this->roleName)) {
$tags[] = ['text' => $this->roleName, 'type' => 'info'];
}
return $tags;
}
/**
* 转换为数组用于API响应
*/
public function toArray(): array
{
return [
'id' => $this->id,
'username' => $this->username,
'email' => $this->email,
'nickname' => $this->nickname,
'phone' => $this->phone,
'avatar' => $this->avatar,
'status' => $this->status,
'status_text' => $this->statusText,
'role_name' => $this->roleName,
'created_at' => $this->createdAt,
'updated_at' => $this->updatedAt,
'last_login_at' => $this->lastLoginAt,
'permissions' => $this->permissions,
'roles' => $this->roles,
'extra' => $this->extra,
// 计算属性
'display_name' => $this->getDisplayName(),
'avatar_url' => $this->getAvatarUrl(),
'phone_display' => $this->getPhoneDisplay(),
'email_display' => $this->getEmailDisplay(),
'is_online' => $this->isOnline(),
'is_active' => $this->isActive(),
'tags' => $this->getTags(),
];
}
/**
* 转换为精简数组(用于列表显示)
*/
public function toSimpleArray(): array
{
return [
'id' => $this->id,
'username' => $this->username,
'nickname' => $this->nickname,
'avatar' => $this->getAvatarUrl(),
'status' => $this->status,
'status_text' => $this->statusText,
'role_name' => $this->roleName,
'is_online' => $this->isOnline(),
'tags' => $this->getTags(),
];
}
/**
* 转换为公开数组(隐藏敏感信息)
*/
public function toPublicArray(): array
{
return [
'id' => $this->id,
'username' => $this->username,
'nickname' => $this->nickname,
'avatar' => $this->getAvatarUrl(),
'role_name' => $this->roleName,
'created_at' => $this->createdAt,
];
}
/**
* 批量转换DTO数组为VO数组
*/
public static function fromDtoArray(array $dtos): array
{
return array_map(fn($dto) => new self($dto), $dtos);
}
/**
* 批量转换为数组
*/
public static function toArrayBatch(array $vos, string $type = 'full'): array
{
return array_map(function($vo) use ($type) {
return match ($type) {
'simple' => $vo->toSimpleArray(),
'public' => $vo->toPublicArray(),
default => $vo->toArray()
};
}, $vos);
}
}