'array', 'category_names' => 'array', 'parts' => 'array', 'images' => 'array', 'operation_fault_steps' => 'array', 'responsible_operators' => 'array', 'repaired_at' => 'integer', 'created_at' => 'integer', 'updated_at' => 'integer', 'deleted_at' => 'integer', ]; public function category(): BelongsTo { return $this->belongsTo(MaterialCategory::class, 'category_id', 'id')->withTrashed(); } public function exception(): BelongsTo { return $this->belongsTo(ExceptionRecord::class, 'exception_id', 'id')->withTrashed(); } public function getExceptionTypeNameAttribute(): string { return (string) ($this->exception?->type_name ?? ''); } public function faultDescription(): BelongsTo { return $this->belongsTo(HardwareFaultDescription::class, 'fault_description_id', 'id')->withTrashed(); } public function getFaultDescriptionNameAttribute(): string { return (string) $this->fault_description; } public function getOrderProductAttribute(): string { return implode('/', array_filter([(string) $this->order_no, (string) $this->product_code])); } public function getRepairResultNameAttribute(): string { return match ($this->repair_result) { 'material_defect' => '物料不良', 'operation_defect' => '作业不良', 'assembly_mismatch' => '搭配错误', 'process_defect' => '工艺不良', 'no_defect' => '不良不现', default => (string) $this->repair_result, }; } public function getResponsibleOperatorNamesAttribute(): string { return implode("\n", array_filter(array_map( static function (array $snapshot): string { $step = (string) ($snapshot['step_name'] ?? ''); $operator = (string) ($snapshot['operator'] ?? $snapshot['user_code'] ?? ''); return implode('-', array_filter([$step, $operator])); }, is_array($this->responsible_operators) ? $this->responsible_operators : [], ))); } public function getPartCategoryAttribute(): string { return $this->formatPartValues(static fn (array $part): string => (string) ($part['category_name'] ?? '')); } public function getPartCodeAttribute(): string { return $this->formatPartValues(static fn (array $part): string => (string) ($part['product_code'] ?? '')); } public function getPartNameAttribute(): string { return $this->formatPartValues(static fn (array $part): string => (string) ($part['product_name'] ?? '')); } public function getPartFaultAttribute(): string { return $this->formatPartValues(static function (array $part): string { return implode('、', array_filter(array_map( static fn (array $fault): string => (string) ($fault['description'] ?? ''), is_array($part['fault_descriptions'] ?? null) ? $part['fault_descriptions'] : [], ))); }); } public function getPartQuantityAttribute(): string { return $this->formatPartValues(static fn (array $part): string => (string) ($part['quantity'] ?? 1)); } public function getPartSourceAttribute(): string { return $this->formatPartValues(static function (array $part): string { return match ($part['source'] ?? '') { 'new' => '新料', 'old', 'after_sale', 'after_sales', 'after-sale' => '售后', 'repair', 'refurbished' => '返修', default => (string) ($part['source'] ?? '-'), }; }); } private function formatPartValues(callable $callback): string { return implode("\n", array_map( static fn (array $part): string => $callback($part) ?: '-', is_array($this->parts) ? $this->parts : [], )); } public function getFaultDescriptionIdsAttribute(): array { return $this->fault_description_id ? [$this->fault_description_id] : []; } public function getFaultDescriptionsAttribute(): array { return $this->fault_description ? [$this->fault_description] : []; } public function getRepairedDateAttribute(): ?string { return $this->repaired_at ? date('Y-m-d H:i:s', (int) $this->repaired_at) : null; } }