You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
11 KiB
11 KiB
后端文件上传封装方法文档
概述
本项目使用了完整的文件上传架构,支持多种存储方式(本地、阿里云OSS、腾讯云COS、七牛云等),并提供了完善的文件管理功能。
核心架构
1. 服务类层次结构
UploadService (API层)
↓
CoreUploadService (核心业务层)
↓
CoreFileService (基础文件服务层)
↓
UploadLoader (存储引擎加载器)
2. 主要组件
- UploadService: API层上传服务,处理前端请求
- CoreUploadService: 核心上传业务逻辑
- CoreFileService: 基础文件操作服务
- CoreImageService: 图片处理服务(缩略图等)
- FileDict: 文件类型字典定义
API接口使用方法
1. 图片上传接口
接口地址: POST /api/upload/image
请求参数:
file: 上传的图片文件
响应示例:
{
"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):
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
use app\service\api\upload\UploadService;
class YourController
{
public function uploadExample()
{
$uploadService = new UploadService();
// 上传图片
$result = $uploadService->image($_FILES['file']);
// 结果包含:
// $result['url'] - 文件访问URL
// $result['att_id'] - 附件ID(如果启用了附件管理)
return success($result);
}
}
2. 使用CoreUploadService(更底层的控制)
<?php
use app\service\core\upload\CoreUploadService;
use app\dict\sys\FileDict;
use app\dict\sys\StorageDict;
class YourService
{
public function customUpload($file)
{
$coreUploadService = new CoreUploadService(true); // true表示写入附件表
// 自定义上传目录和类型
$result = $coreUploadService->image(
$file, // 文件
'custom/path/image', // 自定义目录
0, // 分类ID
StorageDict::LOCAL // 指定存储类型
);
return $result;
}
}
存储配置
1. 存储类型
项目支持以下存储类型:
local: 本地存储aliyun: 阿里云OSSqcloud: 腾讯云COSqiniu: 七牛云
2. 文件类型
支持的文件场景类型(FileDict::getSceneType()):
wechat: 微信相关文件aliyun: 阿里云相关文件image: 图片文件video: 视频文件applet: 小程序包excel: Excel文件
文件路径和URL处理
1. 路径生成规则
// 图片上传路径示例:
// 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转换函数
// 在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. 路径转换辅助函数
// 路径转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. 缩略图生成
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. 设置上传验证规则
$coreFileService = new CoreFileService();
$coreFileService->setValidate([
'ext' => ['jpg', 'jpeg', 'png', 'gif'], // 允许的扩展名
'mime' => ['image/jpeg', 'image/png'], // 允许的MIME类型
'size' => 2 * 1024 * 1024 // 文件大小限制(字节)
]);
2. 设置上传目录
$coreFileService->setRootPath('custom_upload_dir');
完整使用示例
1. 在控制器中处理文件上传
<?php
namespace app\api\controller\example;
use core\base\BaseApiController;
use app\service\api\upload\UploadService;
class FileController extends BaseApiController
{
/**
* 自定义文件上传
*/
public function uploadFile()
{
$data = $this->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
namespace app\service\api\example;
use app\service\core\upload\CoreUploadService;
use core\base\BaseService;
class DocumentService extends BaseService
{
/**
* 批量上传文件并保存记录
*/
public function batchUploadDocuments(array $files, int $relatedId)
{
$uploadService = new CoreUploadService(true); // 启用附件管理
$results = [];
foreach ($files as $file) {
try {
$result = $uploadService->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)
{
// 将上传结果保存到业务表的逻辑
// ...
}
}
注意事项
- 函数缺失问题: 项目中使用了
get_image_url()函数,但在common.php中未定义,建议添加以下代码:
// 添加到 common.php 文件中
if (!function_exists('get_image_url')) {
function get_image_url(string $path): string
{
return get_file_url($path);
}
}
-
token验证: 除头像上传接口外,其他上传接口都需要有效的token
-
文件大小限制: 根据PHP配置和业务需求设置合理的文件大小限制
-
存储空间: 定期清理无用文件,避免存储空间不足
-
安全考虑:
- 验证文件类型和扩展名
- 限制上传文件大小
- 对上传的文件进行安全检查
错误处理
常见错误及解决方案:
- 上传失败: 检查文件大小、类型是否符合要求
- 存储配置错误: 检查存储服务配置是否正确
- 权限问题: 确保上传目录有写入权限
- token失效: 重新获取有效token
测试和验证
1. 登录获取Token
首先需要获取有效的token:
# 员工端登录
curl -X POST "http://localhost:20080/api/login/unified" \
-H "Content-Type: application/json" \
-d '{"username": "19218917377", "password": "19218917377", "login_type": "staff"}'
2. 测试文件上传
使用以下curl命令测试上传功能:
# 测试员工端图片上传
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"
成功响应示例:
{
"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"
}
}
失败响应示例:
{
"code": 0,
"msg": "登录过期,请重新登录",
"data": []
}
3. 验证get_image_url函数
验证体测服务中的文件URL处理:
# 获体测报告列表,验证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"
扩展功能
- 添加新的存储类型: 实现对应的存储驱动类
- 自定义文件处理: 继承CoreUploadService并重写相关方法
- 文件水印: 在图片上传后添加水印处理
- 文件压缩: 对上传的图片进行自动压缩
文档最后更新时间: 2025-01-31