*/ protected $fillable = [ 'pet_id', 'skill_id', 'skill_name', 'start_time', 'end_time', 'status', 'config', ]; /** * 属性类型转换 * * @var array */ protected $casts = [ 'start_time' => 'datetime', 'end_time' => 'datetime', 'config' => 'array', 'created_at' => 'datetime', 'updated_at' => 'datetime', ]; /** * 技能状态常量 */ const STATUS_ACTIVE = 'active'; // 生效中 const STATUS_EXPIRED = 'expired'; // 已过期 const STATUS_CANCELLED = 'cancelled'; // 已取消 /** * 关联宠物 * * @return BelongsTo */ public function pet(): BelongsTo { return $this->belongsTo(PetUser::class, 'pet_id'); } /** * 关联技能配置 * * @return BelongsTo */ public function skill(): BelongsTo { return $this->belongsTo(PetSkill::class, 'skill_id'); } /** * 检查技能是否仍然有效 * * @return bool */ public function isActive(): bool { return $this->status === self::STATUS_ACTIVE && $this->end_time > now(); } /** * 检查技能是否已过期 * * @return bool */ public function isExpired(): bool { return $this->end_time <= now(); } /** * 获取剩余时间(秒) * * @return int */ public function getRemainingSeconds(): int { if ($this->isExpired()) { return 0; } return now()->diffInSeconds($this->end_time); } /** * 标记技能为已过期 * * @return bool */ public function markAsExpired(): bool { $this->status = self::STATUS_EXPIRED; return $this->save(); } /** * 取消技能 * * @return bool */ public function cancel(): bool { $this->status = self::STATUS_CANCELLED; return $this->save(); } /** * 更新最后检查时间 * * @return bool */ public function updateLastCheckTime(): bool { $config = $this->config; // 确保config是数组类型 if (!is_array($config)) { // 如果是字符串,尝试解析JSON if (is_string($config)) { $config = json_decode($config, true); if (json_last_error() !== JSON_ERROR_NONE) { $config = []; } } else { $config = []; } } $config['last_check_time'] = now()->toDateTimeString(); $this->config = $config; return $this->save(); } /** * 获取最后检查时间 * * @return \Carbon\Carbon|null */ public function getLastCheckTime(): ?\Carbon\Carbon { $config = $this->config; // 确保config是数组类型 if (!is_array($config)) { if (is_string($config)) { $config = json_decode($config, true); if (json_last_error() !== JSON_ERROR_NONE) { return null; } } else { return null; } } $lastCheckTime = $config['last_check_time'] ?? null; return $lastCheckTime ? \Carbon\Carbon::parse($lastCheckTime) : null; } /** * 检查是否需要执行检查 * * @return bool */ public function shouldCheck(): bool { if (!$this->isActive()) { return false; } return true; // 无间隔检查 $lastCheckTime = $this->getLastCheckTime(); if (!$lastCheckTime) { return true; } $config = $this->config; // 确保config是数组类型 if (!is_array($config)) { if (is_string($config)) { $config = json_decode($config, true); if (json_last_error() !== JSON_ERROR_NONE) { $config = []; } } else { $config = []; } } $checkInterval = $config['check_interval'] ?? 60; // 默认60秒 return now()->diffInSeconds($lastCheckTime) >= $checkInterval; } /** * 获取技能配置中的特定值 * * @param string $key 配置键名 * @param mixed $default 默认值 * @return mixed */ public function getConfigValue(string $key, $default = null) { $config = $this->config; // 确保config是数组类型 if (!is_array($config)) { if (is_string($config)) { $config = json_decode($config, true); if (json_last_error() !== JSON_ERROR_NONE) { return $default; } } else { return $default; } } return $config[$key] ?? $default; } /** * 设置技能配置中的特定值 * * @param string $key 配置键名 * @param mixed $value 配置值 * @return bool */ public function setConfigValue(string $key, $value): bool { $config = $this->config; // 确保config是数组类型 if (!is_array($config)) { if (is_string($config)) { $config = json_decode($config, true); if (json_last_error() !== JSON_ERROR_NONE) { $config = []; } } else { $config = []; } } $config[$key] = $value; $this->config = $config; return $this->save(); } /** * 查询生效中的技能 * * @param \Illuminate\Database\Eloquent\Builder $query * @return \Illuminate\Database\Eloquent\Builder */ public function scopeActive($query) { return $query->where('status', self::STATUS_ACTIVE) ->where('end_time', '>', now()); } /** * 查询已过期的技能 * * @param \Illuminate\Database\Eloquent\Builder $query * @return \Illuminate\Database\Eloquent\Builder */ public function scopeExpired($query) { return $query->where('end_time', '<=', now()); } /** * 查询特定技能类型 * * @param \Illuminate\Database\Eloquent\Builder $query * @param string $skillName 技能名称 * @return \Illuminate\Database\Eloquent\Builder */ public function scopeBySkillName($query, string $skillName) { return $query->where('skill_name', $skillName); } /** * 查询特定宠物的技能 * * @param \Illuminate\Database\Eloquent\Builder $query * @param int $petId 宠物ID * @return \Illuminate\Database\Eloquent\Builder */ public function scopeByPet($query, int $petId) { return $query->where('pet_id', $petId); } }