# 后端文件上传封装方法文档 ## 概述 本项目使用了完整的文件上传架构,支持多种存储方式(本地、阿里云OSS、腾讯云COS、七牛云等),并提供了完善的文件管理功能。 ## 核心架构 ### 1. 服务类层次结构 ``` UploadService (API层) ↓ CoreUploadService (核心业务层) ↓ CoreFileService (基础文件服务层) ↓ UploadLoader (存储引擎加载器) ``` ### 2. 主要组件 - **UploadService**: API层上传服务,处理前端请求 - **CoreUploadService**: 核心上传业务逻辑 - **CoreFileService**: 基础文件操作服务 - **CoreImageService**: 图片处理服务(缩略图等) - **FileDict**: 文件类型字典定义 ## API接口使用方法 ### 1. 图片上传接口 **接口地址**: `POST /api/upload/image` **请求参数**: - `file`: 上传的图片文件 **响应示例**: ```json { "code": 1, "msg": "SUCCESS", "data": { "url": "https://example.com/upload/file/image/202501/31/1738309123456.jpg", "ext": "jpg", "name": "1738309123456.jpg", "att_id": 123 } } ``` **使用示例 (curl)**: ```bash curl -X POST http://localhost:20080/api/upload/image \ -H "Content-Type: multipart/form-data" \ -H "token: your_token_here" \ -F "file=@/path/to/image.jpg" ``` ### 2. 头像上传接口(无token验证) **接口地址**: `POST /api/upload/avatar` **特点**: - 无需token验证 - 专门用于头像上传 - 存储路径: `file/avatar/年月/日/` ### 3. 视频上传接口 **接口地址**: `POST /api/upload/video` **请求参数**: - `file`: 上传的视频文件 ### 4. 文档上传接口 **接口地址**: `POST /api/upload/document` **请求参数**: - `file`: 上传的文档文件 - `type`: 文档类型(必填),支持的类型见FileDict::getSceneType() ## 服务类使用方法 ### 1. 在业务代码中使用UploadService ```php image($_FILES['file']); // 结果包含: // $result['url'] - 文件访问URL // $result['att_id'] - 附件ID(如果启用了附件管理) return success($result); } } ``` ### 2. 使用CoreUploadService(更底层的控制) ```php image( $file, // 文件 'custom/path/image', // 自定义目录 0, // 分类ID StorageDict::LOCAL // 指定存储类型 ); return $result; } } ``` ## 存储配置 ### 1. 存储类型 项目支持以下存储类型: - `local`: 本地存储 - `aliyun`: 阿里云OSS - `qcloud`: 腾讯云COS - `qiniu`: 七牛云 ### 2. 文件类型 支持的文件场景类型(FileDict::getSceneType()): - `wechat`: 微信相关文件 - `aliyun`: 阿里云相关文件 - `image`: 图片文件 - `video`: 视频文件 - `applet`: 小程序包 - `excel`: Excel文件 ## 文件路径和URL处理 ### 1. 路径生成规则 ```php // 图片上传路径示例: // file/image/202501/31/randomname.jpg $dir = $this->root_path . '/' . 'image' . '/' . date('Ym') . '/' . date('d'); // 头像上传路径示例: // file/avatar/202501/31/randomname.jpg $dir = $this->root_path . '/' . 'avatar' . '/' . date('Ym') . '/' . date('d'); ``` ### 2. URL转换函数 **重要**: 项目中使用的URL转换函数 ```php // 在common.php中定义的函数 function get_file_url(string $path): string { if (!$path) return ''; if (!str_contains($path, 'http://') && !str_contains($path, 'https://')) { return request()->domain() . '/' . path_to_url($path); } else { return path_to_url($path); } } // 注意:项目中使用了get_image_url()函数,但在common.php中未找到定义 // 建议在common.php中添加以下函数作为别名: function get_image_url(string $path): string { return get_file_url($path); } ``` ### 3. 路径转换辅助函数 ```php // 路径转URL function path_to_url($path): string { return trim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '.'); } // URL转路径 function url_to_path($url): string { if (str_contains($url, 'http://') || str_contains($url, 'https://')) { return $url; // 网络图片不转换 } return public_path() . trim(str_replace('/', DIRECTORY_SEPARATOR, $url)); } ``` ## 图片处理功能 ### 1. 缩略图生成 ```php use app\service\core\upload\CoreImageService; $imageService = new CoreImageService(); // 生成缩略图 $thumbs = $imageService->thumb($imagePath, 'all', false); // 或使用全局函数 $thumbs = get_thumb_images($imagePath, 'big', false); ``` ### 2. 缩略图规格 支持的缩略图类型(FileDict::getThumbType()): - `big`: 大图 - `mid`: 中图 - `small`: 小图 ## 文件验证和配置 ### 1. 设置上传验证规则 ```php $coreFileService = new CoreFileService(); $coreFileService->setValidate([ 'ext' => ['jpg', 'jpeg', 'png', 'gif'], // 允许的扩展名 'mime' => ['image/jpeg', 'image/png'], // 允许的MIME类型 'size' => 2 * 1024 * 1024 // 文件大小限制(字节) ]); ``` ### 2. 设置上传目录 ```php $coreFileService->setRootPath('custom_upload_dir'); ``` ## 完整使用示例 ### 1. 在控制器中处理文件上传 ```php request->params([ ['file', 'file'], ['type', 'image'] // 文件类型 ]); $uploadService = new UploadService(); try { // 根据类型选择上传方法 switch ($data['type']) { case 'image': $result = $uploadService->image($data['file']); break; case 'video': $result = $uploadService->video($data['file']); break; case 'document': $result = $uploadService->document($data['file'], 'excel'); break; default: return fail('不支持的文件类型'); } // 添加额外信息 $result['ext'] = pathinfo($result['url'], PATHINFO_EXTENSION); $result['name'] = basename($result['url']); return success($result); } catch (\Exception $e) { return fail($e->getMessage()); } } } ``` ### 2. 在服务类中批量处理文件 ```php document( $file, 'document', 'documents/' . date('Y/m/d'), 'local' ); // 保存文件记录到业务表 $this->saveFileRecord($result, $relatedId); $results[] = $result; } catch (\Exception $e) { // 记录错误但继续处理其他文件 \think\facade\Log::error('文件上传失败: ' . $e->getMessage()); } } return $results; } private function saveFileRecord($uploadResult, $relatedId) { // 将上传结果保存到业务表的逻辑 // ... } } ``` ## 注意事项 1. **函数缺失问题**: 项目中使用了`get_image_url()`函数,但在`common.php`中未定义,建议添加以下代码: ```php // 添加到 common.php 文件中 if (!function_exists('get_image_url')) { function get_image_url(string $path): string { return get_file_url($path); } } ``` 2. **token验证**: 除头像上传接口外,其他上传接口都需要有效的token 3. **文件大小限制**: 根据PHP配置和业务需求设置合理的文件大小限制 4. **存储空间**: 定期清理无用文件,避免存储空间不足 5. **安全考虑**: - 验证文件类型和扩展名 - 限制上传文件大小 - 对上传的文件进行安全检查 ## 错误处理 常见错误及解决方案: 1. **上传失败**: 检查文件大小、类型是否符合要求 2. **存储配置错误**: 检查存储服务配置是否正确 3. **权限问题**: 确保上传目录有写入权限 4. **token失效**: 重新获取有效token ## 测试和验证 ### 1. 登录获取Token 首先需要获取有效的token: ```bash # 员工端登录 curl -X POST "http://localhost:20080/api/login/unified" \ -H "Content-Type: application/json" \ -d '{"username": "19218917377", "password": "19218917377", "login_type": "staff"}' ``` ### 2. 测试文件上传 使用以下curl命令测试上传功能: ```bash # 测试员工端图片上传 curl -X POST http://localhost:20080/api/uploadImage \ -H "token: your_valid_token_here" \ -F "file=@/path/to/image.jpg" # 测试学生端图片上传 curl -X POST http://localhost:20080/api/memberUploadImage \ -H "token: your_valid_token_here" \ -F "file=@/path/to/image.jpg" ``` **成功响应示例**: ```json { "code": 1, "msg": "操作成功", "data": { "url": "https://damai-1345293182.cos.ap-guangzhou.myqcloud.com/upload/file/image/202507/31/1753969912ae14e3ced3c300ff02b7da3688eff61a_tencent.png", "ext": "png", "name": "1753969912ae14e3ced3c300ff02b7da3688eff61a_tencent.png" } } ``` **失败响应示例**: ```json { "code": 0, "msg": "登录过期,请重新登录", "data": [] } ``` ### 3. 验证get_image_url函数 验证体测服务中的文件URL处理: ```bash # 获体测报告列表,验证get_image_url函数处理PDF文件路径 curl -X GET "http://localhost:20080/api/xy/physicalTest?student_id=1&page=1&limit=10" \ -H "token: your_valid_token_here" ``` ## 扩展功能 1. **添加新的存储类型**: 实现对应的存储驱动类 2. **自定义文件处理**: 继承CoreUploadService并重写相关方法 3. **文件水印**: 在图片上传后添加水印处理 4. **文件压缩**: 对上传的图片进行自动压缩 --- *文档最后更新时间: 2025-01-31*