*/ public const EFFECT_OPTIONS = [ 'none', 'fireworks', 'rain', 'lightning', 'snow', ]; /** * 会员进退场支持的横幅风格选项。 * * @var array */ public const BANNER_STYLE_OPTIONS = [ 'aurora', 'storm', 'royal', 'cosmic', 'farewell', ]; /** @var string 表名 */ protected $table = 'vip_levels'; /** @var array 可批量赋值字段 */ protected $fillable = [ 'name', 'icon', 'color', 'exp_multiplier', 'jjb_multiplier', 'join_templates', 'leave_templates', 'join_effect', 'leave_effect', 'join_banner_style', 'leave_banner_style', 'allow_custom_messages', 'sort_order', 'price', 'duration_days', ]; /** @var array 类型转换 */ protected $casts = [ 'exp_multiplier' => 'float', 'jjb_multiplier' => 'float', 'sort_order' => 'integer', 'price' => 'integer', 'duration_days' => 'integer', 'allow_custom_messages' => 'boolean', ]; /** * 关联:该等级下的所有用户 */ public function users(): HasMany { return $this->hasMany(User::class, 'vip_level_id'); } /** * 获取进入聊天室的专属欢迎语模板数组 */ public function getJoinTemplatesArrayAttribute(): array { if (empty($this->join_templates)) { return []; } $decoded = json_decode($this->join_templates, true); return is_array($decoded) ? $decoded : []; } /** * 获取离开聊天室的专属提示语模板数组 */ public function getLeaveTemplatesArrayAttribute(): array { if (empty($this->leave_templates)) { return []; } $decoded = json_decode($this->leave_templates, true); return is_array($decoded) ? $decoded : []; } /** * 从模板数组中随机选一条,替换 {username} 占位符 * * @param array $templates 模板数组 * @param string $username 用户名 */ public static function renderTemplate(array $templates, string $username): ?string { if (empty($templates)) { return null; } $template = $templates[array_rand($templates)]; return str_replace('{username}', $username, $template); } /** * 获取规范化后的入场特效键名。 */ public function joinEffectKey(): string { return in_array($this->join_effect, self::EFFECT_OPTIONS, true) ? (string) $this->join_effect : 'none'; } /** * 获取规范化后的离场特效键名。 */ public function leaveEffectKey(): string { return in_array($this->leave_effect, self::EFFECT_OPTIONS, true) ? (string) $this->leave_effect : 'none'; } /** * 获取规范化后的入场横幅风格键名。 */ public function joinBannerStyleKey(): string { return in_array($this->join_banner_style, self::BANNER_STYLE_OPTIONS, true) ? (string) $this->join_banner_style : 'aurora'; } /** * 获取规范化后的离场横幅风格键名。 */ public function leaveBannerStyleKey(): string { return in_array($this->leave_banner_style, self::BANNER_STYLE_OPTIONS, true) ? (string) $this->leave_banner_style : 'farewell'; } }