validate(['entity_type' => 'required|in:lead,company,deal', 'entity_id' => 'required|integer']); $model = EntityResolver::authorize($validated['entity_type'], $validated['entity_id']); return response()->json(['data' => $model->attachments()->with('uploader:id,name')->latest()->get()]); } public function store(Request $request): JsonResponse { $validated = $request->validate([ 'entity_type' => 'required|in:lead,company,deal', 'entity_id' => 'required|integer', 'file' => 'required|file|mimes:'.$this->allowedMimes().'|max:'.($this->maxFileMb() * 1024), ], [ 'file.mimes' => 'نوع فایل پیوست مجاز نیست.', 'file.max' => 'حجم فایل پیوست بیش از حد مجاز است.', ]); $model = EntityResolver::authorize($validated['entity_type'], $validated['entity_id'], 'update'); $file = $request->file('file'); $path = $file->store('attachments'); $attachment = $model->attachments()->create([ 'uploaded_by' => auth()->id(), 'original_name' => $file->getClientOriginalName(), 'path' => $path, 'mime_type' => $file->getMimeType() ?: 'application/octet-stream', 'size' => $file->getSize(), ]); ActivityLogger::log('attachment_uploaded', "File {$attachment->original_name} uploaded", $model); return response()->json($attachment->load('uploader:id,name'), 201); } public function download(Attachment $attachment) { Gate::authorize('view', $attachment); ActivityLogger::log('attachment_downloaded', "File {$attachment->original_name} downloaded", $attachment->attachable); return Storage::download($attachment->path, $attachment->original_name); } public function destroy(Attachment $attachment): JsonResponse { Gate::authorize('delete', $attachment); Storage::delete($attachment->path); $attachment->delete(); ActivityLogger::log('attachment_deleted', "File {$attachment->id} deleted"); return response()->json(['message' => 'فایل حذف شد']); } private function allowedMimes(): string { return Setting::where('key', 'attachment_allowed_file_types')->value('value') ?: 'pdf,jpg,jpeg,png,doc,docx,xls,xlsx,txt'; } private function maxFileMb(): int { return max(1, (int) (Setting::where('key', 'attachment_max_file_size_mb')->value('value') ?: 10)); } }