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); } }