# Longyi Image Upload Module 一个用于Bagisto的图片上传模块,支持上传到AWS S3或其他存储驱动。 ## 功能特性 - ✅ 支持单张图片上传 - ✅ 支持多张图片批量上传 - ✅ 支持AWS S3存储 - ✅ 支持本地存储 - ✅ 自动图片优化(转换为WebP格式) - ✅ 文件大小和类型验证 - ✅ 自定义上传目录 - ✅ 图片删除功能 - ✅ 中英文界面支持 - ✅ **管理后台和前端都支持** - ✅ **提供Vue组件供前端使用** ## 安装 ### 1. 添加依赖 在项目的根目录运行: ```bash composer require longyi/image-upload ``` 或者手动添加到 `composer.json`: ```json { "require": { "longyi/image-upload": "^1.0" } } ``` ### 2. 配置AWS S3(如果使用S3存储) 在 `.env` 文件中添加以下配置: ```env # 设置默认上传磁盘为s3 IMAGE_UPLOAD_DISK=s3 # AWS S3 配置 AWS_ACCESS_KEY_ID=your-access-key-id AWS_SECRET_ACCESS_KEY=your-secret-access-key AWS_DEFAULT_REGION=your-region AWS_BUCKET=your-bucket-name AWS_URL=https://your-bucket.s3.your-region.amazonaws.com AWS_USE_PATH_STYLE_ENDPOINT=false # 可选:设置最大上传大小(KB) IMAGE_UPLOAD_MAX_SIZE=5120 ``` ### 3. 发布配置文件(可选) ```bash php artisan vendor:publish --provider="Longyi\ImageUpload\Providers\ImageUploadServiceProvider" --tag=config ``` ### 4. 清除缓存 ```bash php artisan config:clear php artisan cache:clear ``` ## 使用方法 ### 管理后台访问 访问管理后台的图片上传页面: ``` /admin/image-upload ``` ### 前端 API 使用 前端用户可以通过 API 上传图片,所有接口都在 `/api/image-upload` 路径下。 #### 1. 上传单张图片(前端) **请求:** ```http POST /api/image-upload/upload Content-Type: multipart/form-data image: [file] directory: shop/uploads (可选,默认为 shop/uploads) ``` **响应:** ```json { "success": true, "message": "Image uploaded successfully", "data": { "success": true, "path": "shop/uploads/2026/05/27/abc123.webp", "url": "https://bucket.s3.region.amazonaws.com/shop/uploads/2026/05/27/abc123.webp", "original_name": "photo.jpg", "mime_type": "image/jpeg", "size": 102400, "disk": "s3" } } ``` #### 2. 上传多张图片(前端) **请求:** ```http POST /api/image-upload/upload-multiple Content-Type: multipart/form-data images[]: [file1] images[]: [file2] directory: shop/uploads (可选) ``` **限制:** - 最多上传 10 张图片 - 每张不超过配置的最大大小 ### Vue 组件使用 模块提供了一个现成的 Vue 组件,可以在前端页面中使用: ```vue ``` ### JavaScript/Fetch 使用示例 如果你不使用 Vue,也可以直接用 JavaScript 调用 API: ```javascript // 单张图片上传 async function uploadImage(file) { const formData = new FormData(); formData.append('image', file); formData.append('directory', 'custom/path'); try { const response = await fetch('/api/image-upload/upload', { method: 'POST', body: formData, headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content } }); const data = await response.json(); if (data.success) { console.log('上传成功:', data.data.url); return data.data; } else { console.error('上传失败:', data.message); } } catch (error) { console.error('错误:', error); } } // 多张图片上传 async function uploadMultipleImages(files) { const formData = new FormData(); files.forEach(file => { formData.append('images[]', file); }); formData.append('directory', 'custom/path'); try { const response = await fetch('/api/image-upload/upload-multiple', { method: 'POST', body: formData, headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content } }); const data = await response.json(); if (data.success) { console.log('上传成功:', data.data); return data.data; } else { console.error('上传失败:', data.message); } } catch (error) { console.error('错误:', error); } } // 使用示例 document.getElementById('imageInput').addEventListener('change', async (e) => { const file = e.target.files[0]; if (file) { const result = await uploadImage(file); // 使用 result.url 显示图片或保存到数据库 document.getElementById('preview').src = result.url; } }); ``` ### 管理后台 API 使用 以下 API 端点用于管理后台(需要管理员权限): #### 1. 上传单张图片(管理后台) **请求:** ```http POST /admin/image-upload/upload Content-Type: multipart/form-data image: [file] directory: custom/path (可选) ``` **响应:** ```json { "success": true, "message": "Image uploaded successfully", "data": { "success": true, "path": "images/uploads/2026/05/27/abc123.webp", "url": "https://bucket.s3.region.amazonaws.com/images/uploads/2026/05/27/abc123.webp", "original_name": "photo.jpg", "mime_type": "image/jpeg", "size": 102400, "disk": "s3" } } ``` #### 2. 上传多张图片(管理后台) **请求:** ```http POST /admin/image-upload/upload-multiple Content-Type: multipart/form-data images[]: [file1] images[]: [file2] directory: custom/path (可选) ``` **响应:** ```json { "success": true, "message": "2 images uploaded successfully, 0 failed", "data": [ { "success": true, "path": "images/uploads/2026/05/27/abc123.webp", "url": "https://...", "original_name": "photo1.jpg", "mime_type": "image/jpeg", "size": 102400, "disk": "s3" }, { "success": true, "path": "images/uploads/2026/05/27/def456.webp", "url": "https://...", "original_name": "photo2.jpg", "mime_type": "image/jpeg", "size": 204800, "disk": "s3" } ] } ``` #### 3. 删除图片(管理后台) **请求:** ```http DELETE /admin/image-upload/delete Content-Type: application/json { "path": "images/uploads/2026/05/27/abc123.webp", "disk": "s3" (可选) } ``` **响应:** ```json { "success": true, "message": "Image deleted successfully" } ``` #### 4. 获取图片URL(管理后台) **请求:** ```http GET /admin/image-upload/url?path=images/uploads/2026/05/27/abc123.webp&disk=s3 ``` **响应:** ```json { "success": true, "url": "https://bucket.s3.region.amazonaws.com/images/uploads/2026/05/27/abc123.webp" } ``` ### API 路由对比 | 功能 | 管理后台路由 | 前端路由 | 说明 | |------|------------|---------|------| | 上传单张 | POST `/admin/image-upload/upload` | POST `/api/image-upload/upload` | 前端默认目录为 `shop/uploads` | | 上传多张 | POST `/admin/image-upload/upload-multiple` | POST `/api/image-upload/upload-multiple` | 前端最多10张 | | 删除图片 | DELETE `/admin/image-upload/delete` | DELETE `/api/image-upload/delete` | - | | 获取URL | GET `/admin/image-upload/url` | GET `/api/image-upload/url` | - | **主要区别:** - **管理后台**:需要管理员权限,路径为 `/admin/*` - **前端**:无需特殊权限(或需要登录),路径为 `/api/*`,默认上传到 `shop/uploads` 目录 ## 代码中使用 ```php use Longyi\ImageUpload\Services\ImageUploadService; // 注入服务 public function __construct( protected ImageUploadService $imageUploadService ) {} // 上传单张图片 public function uploadImage(Request $request) { $file = $request->file('image'); $result = $this->imageUploadService->upload($file, 'custom/directory'); if ($result['success']) { // 使用 $result['url'] 或 $result['path'] } } // 上传多张图片 public function uploadImages(Request $request) { $files = $request->file('images'); $results = $this->imageUploadService->uploadMultiple($files, 'custom/directory'); foreach ($results as $result) { if ($result['success']) { // 处理成功的上传 } } } // 删除图片 public function deleteImage(string $path) { $deleted = $this->imageUploadService->delete($path); if ($deleted) { // 删除成功 } } // 获取图片URL public function getImageUrl(string $path) { $url = $this->imageUploadService->getUrl($path); return $url; } ``` ## 配置说明 配置文件位于 `config/image_upload.php`: ```php return [ // 默认存储磁盘:'local' 或 's3' 'default_disk' => env('IMAGE_UPLOAD_DISK', 's3'), // 允许的图片类型 'allowed_types' => [ 'image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml', ], // 最大文件大小(KB) 'max_size' => env('IMAGE_UPLOAD_MAX_SIZE', 5120), // 上传目录 'upload_directory' => 'images/uploads', // S3配置 's3' => [ 'bucket' => env('AWS_BUCKET'), 'region' => env('AWS_DEFAULT_REGION'), 'visibility' => 'public', ], ]; ``` ## 扩展其他存储方式 要添加其他存储方式(如阿里云OSS、腾讯云COS等),只需: 1. 安装相应的Flysystem适配器 2. 在 `config/filesystems.php` 中配置新的disk 3. 修改 `IMAGE_UPLOAD_DISK` 环境变量或使用新的disk名称 例如,添加阿里云OSS: ```bash composer require aliyuncs/oss-sdk-php composer require jacobcyl/ali-oss-storage ``` 在 `config/filesystems.php` 中添加: ```php 'oss' => [ 'driver' => 'oss', 'access_id' => env('ALIYUN_ACCESS_KEY_ID'), 'access_key' => env('ALIYUN_ACCESS_KEY_SECRET'), 'bucket' => env('ALIYUN_BUCKET'), 'endpoint' => env('ALIYUN_ENDPOINT'), ], ``` 然后设置 `IMAGE_UPLOAD_DISK=oss` 即可。 ## 依赖要求 - PHP >= 8.1 - Laravel >= 10.0 - intervention/image - league/flysystem-aws-s3-v3 (用于S3支持) ## 许可证 MIT License ## 作者 Longyi Team