本系统提供三种类型的文件上传接口,分别用于不同的使用场景:
| 接口 | 适用场景 | 文件大小限制 | 特点 |
|---|---|---|---|
upload_image | 图片上传 | 1KB - 50MB | 自动压缩生成多尺寸 |
upload_video | 视频上传 | 1KB - 50MB | 保留原始文件 |
upload_file | 小文件直传 | 1KB - 2GB | 简单直接 |
upload_file_template_url + upload_file_success | 大文件上传 | 无限制 | 预签名URL,客户端直传S3 |
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
file | file | 是 | 图片文件 |
scene | string | 否 | 使用场景标识,��认 default |
文件限制:
jpg, png, jpeg, gif, webp| 字段 | 类型 | 说明 |
|---|---|---|
id | int | 上传图片记录ID |
url_og | string | 原始图片URL |
url_sm | string | 小尺寸缩略图URL (320px宽) |
url_md | string | 中尺寸缩略图URL (650px宽) |
url_lg | string | 大尺寸缩略图URL (1250px宽) |
width | int | 图片宽度(压缩完成后更新) |
height | int | 图片高度(压缩完成后更新) |
mime | string | MIME类型 |
size | int | 文件大小(字节) |
上传完成后,系统会异步执行图片压缩任务(CompressImage Job):
压缩尺寸:
sm: 320px 宽度md: 650px 宽度lg: 1250px 宽度输出格式:统一转换为 webp 格式
压缩工具:
cwebp,失败时降级到 ImageMagickImageMagick 缩放 + gif2webp 转换压缩质量:80%
处理超时:30分钟
调用 UploadService::deleteUploadImage($uploadImageId) 时:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
file | file | 是 | 视频文件 |
scene | string | 否 | 使用场景标识,默认 default |
文件限制:
mp4| 字段 | 类型 | 说明 |
|---|---|---|
id | int | 上传视频记录ID |
url_sm | string | 小尺寸视频URL(当前与原始相同) |
url_md | string | 中尺寸视频URL(当前与原始相同) |
url_lg | string | 大尺寸视频URL(当前与原始相同) |
mime | string | MIME类型 |
size | int | 文件大小(字节) |
当前视频上传不进行压缩处理,url_sm、url_md、url_lg 均指向原始文件。
调用 UploadService::deleteUploadVideo($uploadVideoId) 时:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
file | file | 是 | 任意文件 |
scene | string | 否 | 使用场景标识,默认 default |
文件限制:
| 字段 | 类型 | 说明 |
|---|---|---|
id | int | 上传文件记录ID |
name | string | 原始文件名 |
url_og | string | 文件URL |
mime | string | MIME类型 |
size | int | 文件大小(字节) |
state | string | 状态:successed |
expired_at | string/null | 过期时间(仅 scene=chat 时有值) |
适用于大文件上传,分两步完成:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 是 | 文件名(含扩展名) |
scene | string | 否 | 使用场景标识,默认 default |
| 字段 | 类型 | 说明 |
|---|---|---|
upload_file_id | int | 上传文件记录ID,用于后续确认 |
file_path | string | 文件存储路径 |
url | string | 预签名上传URL(有效期1小时) |
headers | object | 上传时需要携带的请求头 |
客户端使用预签名URL上传完成后,调用此接口确认。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | int | 是 | upload_file_template_url 返回的 upload_file_id |
状态码:400(文件未在存储中找到)
UploadFile 模型的 state 字段:
| 状态 | 值 | 说明 |
|---|---|---|
| Pending | pending | 等待上传(预签名URL已生成,文件未上传) |
| Successed | successed | 上传成功 |
| Deleted | deleted | 已删除(定时任务清理后的状态) |
系统每天执行 DeleteExpiredUploadFile 定时任务,清理过期的聊天文件:
清理条件:
scene = 'chat'(仅清理聊天场景的文件)state != 'deleted'(未被删除的文件)created_at < 当前时间 - 3个月(创建时间超过3个月)清理操作:
state 更新为 deleted对于 scene = 'chat' 的文件,expired_at 字段会自动计算:
expired_at 值,直接使用created_at + 3个月计算其他场景的文件 expired_at 为 null,不会被自动清理。
定时任务在 routes/console.php 中配置,每天执行一次:
| 特性 | upload_image | upload_video | upload_file | upload_file_template_url |
|---|---|---|---|---|
| 上传方式 | 服务器中转 | 服务器中转 | 服务器中转 | 客户端直传S3 |
| 文件大小 | ≤50MB | ≤50MB | ≤2GB | 无限制 |
| 自动压缩 | ✅ 生成3种尺寸 | ❌ | ❌ | ❌ |
| 适用文件 | 图片 | 视频 | 任意 | 任意 |
| 调用次数 | 1次 | 1次 | 1次 | 2次 |
| 服务器压力 | 高(压缩) | 中 | 高(大文件) | 低 |
upload_image,自动获得多尺寸缩略图upload_videoupload_file,简单直接upload_file_template_url + upload_file_success,减轻服务器压力scene=chat,系统会在3个月后自动清理所有上传文件按以下规则组织:
top_folder: upload_images / upload_videos / upload_filesuser_id: 上传用户IDscene: 使用场景标识date: 上传日期 (YYYY-MM-DD)unique_id: 唯一标识符 (uniqid)suffix: og(原始) / sm(小) / md(中) / lg(大)