*/ protected $fillable = [ 'emoji', 'name', 'message', 'exp', 'jjb', 'weight', 'is_active', 'sort', ]; /** * 字段类型转换 * * @return array */ protected function casts(): array { return [ 'exp' => 'integer', 'jjb' => 'integer', 'weight' => 'integer', 'is_active' => 'boolean', 'sort' => 'integer', ]; } /** * 作用域:只查询已启用的事件 */ public function scopeActive(Builder $query): Builder { return $query->where('is_active', true); } /** * 根据权重随机抽取一个激活的钓鱼事件 * * 实现加权随机:权重越大,被选中概率越高。 * 若无任何激活事件,返回 null。 */ public static function rollOne(): ?static { $events = static::active()->orderBy('sort')->get(); if ($events->isEmpty()) { return null; } // 计算总权重后加权随机 $totalWeight = $events->sum('weight'); $roll = random_int(1, max($totalWeight, 1)); $cumulative = 0; foreach ($events as $event) { $cumulative += $event->weight; if ($roll <= $cumulative) { return $event; } } // 兜底:返回最后一个 return $events->last(); } }