'array', 'attempts' => 'integer', 'reserved_at' => 'integer', 'available_at' => 'integer', 'created_at' => 'integer', 'runtime' => 'float' ]; protected $appends = [ 'queue_name', 'run_class_name', 'created_at_formatted', 'available_at_formatted', 'reserved_at_formatted', 'status_label', 'status_color', 'runtime_formatted', 'job_class', 'desc_short', 'job_parameters', 'job_parameters_short' ]; //attrlist start public static $attrlist = [ 'id', 'queue', 'payload', 'runclass', 'attempts', 'reserved_at', 'available_at', 'created_at', 'status', 'desc', 'runtime' ]; //attrlist end /** * 获取队列名称访问器 */ public function getQueueNameAttribute(): string { return $this->queue ?? 'default'; } /** * 获取运行类名访问器 */ public function getRunClassNameAttribute(): string { if (!$this->runclass) { return ''; } // 提取类名(去掉命名空间) $parts = explode('\\', $this->runclass); return end($parts); } /** * 获取格式化的创建时间 */ public function getCreatedAtFormattedAttribute(): string { return $this->created_at ? date('Y-m-d H:i:s', $this->created_at) : ''; } /** * 获取格式化的可用时间 */ public function getAvailableAtFormattedAttribute(): string { return $this->available_at ? date('Y-m-d H:i:s', $this->available_at) : ''; } /** * 获取格式化的保留时间 */ public function getReservedAtFormattedAttribute(): string { return $this->reserved_at ? date('Y-m-d H:i:s', $this->reserved_at) : ''; } /** * 获取状态标签 */ public function getStatusLabelAttribute(): string { $status = $this->status; // 处理带数字后缀的状态 if (strpos($status, 'runend-') === 0) { return '已完成'; } if (strpos($status, 'run-') === 0) { return '运行中'; } switch ($status) { case 'success': case 'run-end': return '已完成'; case 'failed': case 'error': return '失败'; case 'running': case 'run': return '运行中'; case 'pending': case 'wait': return '待处理'; default: return $status ?? '未知'; } } /** * 获取状态颜色 */ public function getStatusColorAttribute(): string { $status = $this->status; // 处理带数字后缀的状态 if (strpos($status, 'runend-') === 0) { return 'success'; } if (strpos($status, 'run-') === 0) { return 'warning'; } switch ($status) { case 'success': case 'run-end': return 'success'; case 'failed': case 'error': return 'danger'; case 'running': case 'run': return 'warning'; case 'pending': case 'wait': return 'info'; default: return 'secondary'; } } /** * 获取格式化的运行时间 */ public function getRuntimeFormattedAttribute(): string { if (!$this->runtime) { return ''; } if ($this->runtime < 1) { return round($this->runtime * 1000, 2) . 'ms'; } else { return round($this->runtime, 3) . 's'; } } /** * 获取任务类名(从payload中提取) */ public function getJobClassAttribute(): string { if (!$this->payload) { return $this->runclass ?? ''; } $payload = is_array($this->payload) ? $this->payload : json_decode($this->payload, true); return $payload['displayName'] ?? $payload['job'] ?? $this->runclass ?? ''; } /** * 获取描述信息(截断) */ public function getDescShortAttribute(): string { if (!$this->desc) { return ''; } return mb_strlen($this->desc) > 100 ? mb_substr($this->desc, 0, 100) . '...' : $this->desc; } /** * 获取任务参数 */ public function getJobParametersAttribute(): string { if (!$this->payload) { return ''; } // 尝试解析payload $payload = $this->payload; // 如果是字符串,尝试反序列化 if (is_string($payload)) { // 去掉外层引号 $payload = trim($payload, '"'); // 尝试反序列化PHP数组 if (strpos($payload, 'a:') === 0) { try { $unserialized = unserialize($payload); if (is_array($unserialized)) { $payload = $unserialized; } } catch (\Exception) { // 反序列化失败,保持原样 } } else { // 尝试JSON解码 $decoded = json_decode($payload, true); if (json_last_error() === JSON_ERROR_NONE) { $payload = $decoded; } } } if (is_array($payload)) { $params = []; foreach ($payload as $key => $value) { if ($key === 'runtime') { $params['运行时间'] = round($value, 3) . 's'; } else { $params[$key] = is_scalar($value) ? $value : json_encode($value); } } if (empty($params)) { return '无参数'; } $result = []; foreach ($params as $key => $value) { $result[] = "{$key}: {$value}"; } return implode(', ', $result); } return $payload ?: '无参数'; } /** * 获取简化的任务参数(用于列表显示) */ public function getJobParametersShortAttribute(): string { $params = $this->job_parameters; if (mb_strlen($params) > 50) { return mb_substr($params, 0, 50) . '...'; } return $params; } }