*/ public function buildJoinTheme(User $user): array { return $this->buildTheme($user, 'join'); } /** * 构建会员离场主题数据。 * * @return array */ public function buildLeaveTheme(User $user): array { return $this->buildTheme($user, 'leave'); } /** * 统一构建会员进场或离场的主题数据。 * * @param string $type join|leave * @return array */ private function buildTheme(User $user, string $type): array { $vipLevel = $user->vipLevel; if (! $user->isVip() || ! $vipLevel) { return [ 'enabled' => false, 'type' => $type, 'text' => null, 'color' => null, 'effect' => null, 'banner_style' => null, 'level_name' => null, 'icon' => null, ]; } // 先读取个人自定义文案,只有等级允许时才参与覆盖。 $customMessage = $type === 'join' ? $this->formatCustomMessage($user->custom_join_message, $user->username) : $this->formatCustomMessage($user->custom_leave_message, $user->username); if (! $user->canCustomizeVipPresence()) { $customMessage = null; } // 如果用户没有填写自定义文案,则回退到等级模板。 $templateMessage = $type === 'join' ? $this->vipService->getJoinMessage($user) : $this->vipService->getLeaveMessage($user); return [ 'enabled' => true, 'type' => $type, 'text' => $customMessage ?: $templateMessage, 'color' => $vipLevel->color ?: '#f59e0b', 'effect' => $type === 'join' ? $this->normalizeEffect($vipLevel->joinEffectKey()) : $this->normalizeEffect($vipLevel->leaveEffectKey()), 'banner_style' => $type === 'join' ? $vipLevel->joinBannerStyleKey() : $vipLevel->leaveBannerStyleKey(), 'level_name' => $vipLevel->name, 'icon' => $vipLevel->icon, ]; } /** * 格式化用户自定义文案,支持 {username} 占位符。 */ private function formatCustomMessage(?string $message, string $username): ?string { $message = trim((string) $message); if ($message === '') { return null; } return str_replace('{username}', $username, $message); } /** * 把 none 这类占位值转换为 null,方便外部判断是否要播特效。 */ private function normalizeEffect(string $effect): ?string { return $effect === 'none' ? null : $effect; } }