validate([ 'file' => ['required', 'file', 'image', 'max:5120'], 'subdir' => ['required', 'string', 'in:covers,promos'], ]); $uploaded = $request->file('file'); $path = $uploaded->store("courses/{$data['subdir']}", 'public'); $url = CourseMedia::publicAssetUrl($path) ?? ''; $media = CourseMedia::query()->create([ 'disk' => 'public', 'path' => $path, 'url' => $url, 'category' => $data['subdir'], 'original_name' => $uploaded->getClientOriginalName(), 'mime_type' => $uploaded->getClientMimeType(), 'size_bytes' => $uploaded->getSize() ?: null, ]); return $this->ok($media->toApiArray(), '已上传'); } /** 资讯封面图上传,存 public 盘并返回 URL */ public function newsCover(Request $request): JsonResponse { $data = $request->validate([ 'file' => ['required', 'file', 'image', 'max:5120'], ]); $uploaded = $request->file('file'); $path = $uploaded->store('news/covers', 'public'); $url = CourseMedia::publicAssetUrl($path) ?? ''; return $this->ok(['url' => $url], '已上传'); } /** Banner 自定义封面图上传 */ public function bannerCover(Request $request): JsonResponse { $data = $request->validate([ 'file' => ['required', 'file', 'image', 'max:5120'], ]); $uploaded = $request->file('file'); $path = $uploaded->store('banners/covers', 'public'); $url = CourseMedia::publicAssetUrl($path) ?? ''; return $this->ok(['url' => $url], '已上传'); } }