- 添加认证相关API文档(登录认证、验证码) - 添加权限管理API文档(菜单管理、角色管理) - 添加系统管理API文档(图片管理、文件管理、登录日志) - 添加用户管理API文档 - 完善项目API文档结构,提升开发体验
24 KiB
图片管理API
概述
图片管理模块专门用于管理系统中的图片资源,提供图片的上传、存储、展示和管理功能。支持多种图片格式,具备图片压缩、水印、缩略图生成等高级功能。
权限说明
图片管理接口需要相应的权限才能访问:
| 操作 | 权限码 | 说明 |
|---|---|---|
| 查询图片列表 | system:picture:list |
查看图片列表权限 |
| 上传图片 | system:picture:upload |
上传图片权限 |
| 删除图片 | system:picture:remove |
删除图片权限 |
| 编辑图片 | system:picture:edit |
编辑图片信息权限 |
接口列表
1. 分页查询图片列表
接口地址: GET /coder/sysPicture/listPage
接口描述: 分页查询系统图片列表
是否需要认证: 是
权限要求: system:picture:list
请求头:
Authorization: Bearer your-token-value
请求参数:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| pageNo | Integer | 否 | 页码 | 1 |
| pageSize | Integer | 否 | 每页大小 | 10 |
| pictureName | String | 否 | 图片名称 | banner.jpg |
| pictureType | String | 否 | 图片类型 | jpg |
| albumName | String | 否 | 相册名称 | banner |
| pictureStatus | String | 否 | 图片状态 | 0 |
| beginTime | String | 否 | 开始时间 | 2024-01-01 |
| endTime | String | 否 | 结束时间 | 2024-12-31 |
响应示例:
{
"status": 200,
"msg": "SUCCESS",
"data": {
"records": [
{
"pictureId": 1,
"pictureName": "banner_20240705_001.jpg",
"originalName": "主页横幅.jpg",
"picturePath": "/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg",
"pictureUrl": "http://localhost:18099/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg",
"thumbnailUrl": "http://localhost:18099/upload/pictures/banner/2024/07/05/thumb_banner_20240705_001.jpg",
"albumName": "banner",
"pictureSize": 2048000,
"pictureType": "jpg",
"pictureFormat": "JPEG",
"width": 1920,
"height": 1080,
"pictureStatus": "0",
"isWatermark": "0",
"uploadUserId": 1,
"uploadUserName": "admin",
"description": "主页横幅图片",
"tags": "横幅,主页,展示",
"viewCount": 100,
"downloadCount": 10,
"remark": "网站主页横幅",
"createBy": "admin",
"createTime": "2024-07-05 10:00:00",
"updateBy": "admin",
"updateTime": "2024-07-05 10:00:00"
}
],
"total": 1,
"size": 10,
"current": 1,
"pages": 1
},
"traceId": "trace-123456"
}
调用示例:
curl -X GET \
"http://localhost:18099/coder/sysPicture/listPage?pageNo=1&pageSize=10&albumName=banner" \
-H "Authorization: Bearer your-token-value"
2. 查询所有图片
接口地址: GET /coder/sysPicture/list
接口描述: 查询所有系统图片(不分页)
是否需要认证: 是
权限要求: system:picture:list
请求参数: 同分页查询(除pageNo、pageSize外)
响应示例:
{
"status": 200,
"msg": "SUCCESS",
"data": [
{
"pictureId": 1,
"pictureName": "banner_20240705_001.jpg",
"originalName": "主页横幅.jpg",
"picturePath": "/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg",
"pictureUrl": "http://localhost:18099/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg",
"thumbnailUrl": "http://localhost:18099/upload/pictures/banner/2024/07/05/thumb_banner_20240705_001.jpg",
"albumName": "banner",
"pictureSize": 2048000,
"pictureType": "jpg",
"pictureFormat": "JPEG",
"width": 1920,
"height": 1080,
"pictureStatus": "0",
"isWatermark": "0",
"uploadUserId": 1,
"uploadUserName": "admin",
"description": "主页横幅图片",
"tags": "横幅,主页,展示",
"viewCount": 100,
"downloadCount": 10,
"remark": "网站主页横幅",
"createBy": "admin",
"createTime": "2024-07-05 10:00:00",
"updateBy": "admin",
"updateTime": "2024-07-05 10:00:00"
}
],
"traceId": "trace-123456"
}
调用示例:
curl -X GET \
"http://localhost:18099/coder/sysPicture/list?albumName=banner" \
-H "Authorization: Bearer your-token-value"
3. 根据ID查询图片
接口地址: GET /coder/sysPicture/getById/{id}
接口描述: 根据图片ID查询图片详细信息
是否需要认证: 是
权限要求: system:picture:list
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 图片ID |
响应示例:
{
"status": 200,
"msg": "SUCCESS",
"data": {
"pictureId": 1,
"pictureName": "banner_20240705_001.jpg",
"originalName": "主页横幅.jpg",
"picturePath": "/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg",
"pictureUrl": "http://localhost:18099/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg",
"thumbnailUrl": "http://localhost:18099/upload/pictures/banner/2024/07/05/thumb_banner_20240705_001.jpg",
"albumName": "banner",
"pictureSize": 2048000,
"pictureType": "jpg",
"pictureFormat": "JPEG",
"width": 1920,
"height": 1080,
"pictureStatus": "0",
"isWatermark": "0",
"uploadUserId": 1,
"uploadUserName": "admin",
"description": "主页横幅图片",
"tags": "横幅,主页,展示",
"viewCount": 100,
"downloadCount": 10,
"remark": "网站主页横幅",
"createBy": "admin",
"createTime": "2024-07-05 10:00:00",
"updateBy": "admin",
"updateTime": "2024-07-05 10:00:00"
},
"traceId": "trace-123456"
}
调用示例:
curl -X GET \
http://localhost:18099/coder/sysPicture/getById/1 \
-H "Authorization: Bearer your-token-value"
4. 新增图片记录
接口地址: POST /coder/sysPicture/add
接口描述: 新增系统图片记录
是否需要认证: 是
权限要求: system:picture:upload
请求参数:
{
"pictureName": "product_20240705_001.jpg",
"originalName": "产品展示图.jpg",
"picturePath": "/upload/pictures/product/2024/07/05/product_20240705_001.jpg",
"pictureUrl": "http://localhost:18099/upload/pictures/product/2024/07/05/product_20240705_001.jpg",
"thumbnailUrl": "http://localhost:18099/upload/pictures/product/2024/07/05/thumb_product_20240705_001.jpg",
"albumName": "product",
"pictureSize": 1536000,
"pictureType": "jpg",
"pictureFormat": "JPEG",
"width": 1200,
"height": 800,
"pictureStatus": "0",
"isWatermark": "1",
"uploadUserId": 1,
"uploadUserName": "admin",
"description": "产品展示图片",
"tags": "产品,展示,商品",
"remark": "商品详情页图片"
}
请求参数说明:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|---|---|---|---|---|
| pictureName | String | 是 | 存储图片名 | 不能为空 |
| originalName | String | 是 | 原始图片名 | 不能为空 |
| picturePath | String | 是 | 图片相对路径 | 不能为空 |
| pictureUrl | String | 是 | 图片访问URL | 不能为空 |
| thumbnailUrl | String | 否 | 缩略图URL | 可为空 |
| albumName | String | 是 | 相册名称 | 不能为空 |
| pictureSize | Long | 是 | 图片大小 | 必须大于0 |
| pictureType | String | 是 | 图片类型 | 不能为空 |
| pictureFormat | String | 是 | 图片格式 | 不能为空 |
| width | Integer | 否 | 图片宽度 | 大于0 |
| height | Integer | 否 | 图片高度 | 大于0 |
| pictureStatus | String | 是 | 图片状态 | 0-正常 1-删除 |
| isWatermark | String | 否 | 是否水印 | 0-否 1-是 |
| uploadUserId | Long | 否 | 上传用户ID | 有效的用户ID |
| uploadUserName | String | 否 | 上传用户名 | 可为空 |
| description | String | 否 | 图片描述 | 最长500字符 |
| tags | String | 否 | 图片标签 | 逗号分隔 |
| remark | String | 否 | 备注信息 | 最长200字符 |
响应示例:
{
"status": 200,
"msg": "SUCCESS",
"data": "新增成功",
"traceId": "trace-123456"
}
调用示例:
curl -X POST \
http://localhost:18099/coder/sysPicture/add \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-value" \
-d '{
"pictureName": "product_20240705_001.jpg",
"originalName": "产品展示图.jpg",
"picturePath": "/upload/pictures/product/2024/07/05/product_20240705_001.jpg",
"pictureUrl": "http://localhost:18099/upload/pictures/product/2024/07/05/product_20240705_001.jpg",
"albumName": "product",
"pictureSize": 1536000,
"pictureType": "jpg",
"pictureFormat": "JPEG",
"width": 1200,
"height": 800,
"pictureStatus": "0",
"description": "产品展示图片",
"tags": "产品,展示,商品"
}'
5. 修改图片信息
接口地址: POST /coder/sysPicture/update
接口描述: 修改系统图片记录信息
是否需要认证: 是
权限要求: system:picture:edit
请求参数:
{
"pictureId": 1,
"pictureName": "product_20240705_001.jpg",
"originalName": "产品展示图.jpg",
"picturePath": "/upload/pictures/product/2024/07/05/product_20240705_001.jpg",
"pictureUrl": "http://localhost:18099/upload/pictures/product/2024/07/05/product_20240705_001.jpg",
"thumbnailUrl": "http://localhost:18099/upload/pictures/product/2024/07/05/thumb_product_20240705_001.jpg",
"albumName": "product",
"pictureSize": 1536000,
"pictureType": "jpg",
"pictureFormat": "JPEG",
"width": 1200,
"height": 800,
"pictureStatus": "0",
"isWatermark": "1",
"uploadUserId": 1,
"uploadUserName": "admin",
"description": "产品展示图片(已更新)",
"tags": "产品,展示,商品,新品",
"remark": "商品详情页图片(已更新)"
}
请求参数说明:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|---|---|---|---|---|
| pictureId | Long | 是 | 图片ID | 必须是有效的图片ID |
| 其他参数 | - | - | 同新增图片记录 | - |
响应示例:
{
"status": 200,
"msg": "SUCCESS",
"data": "修改成功",
"traceId": "trace-123456"
}
调用示例:
curl -X POST \
http://localhost:18099/coder/sysPicture/update \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-value" \
-d '{
"pictureId": 1,
"description": "产品展示图片(已更新)",
"tags": "产品,展示,商品,新品"
}'
6. 删除图片
接口地址: POST /coder/sysPicture/deleteById/{id}
接口描述: 根据ID删除图片记录和物理文件
是否需要认证: 是
权限要求: system:picture:remove
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 图片ID |
响应示例:
{
"status": 200,
"msg": "SUCCESS",
"data": "删除成功",
"traceId": "trace-123456"
}
调用示例:
curl -X POST \
http://localhost:18099/coder/sysPicture/deleteById/1 \
-H "Authorization: Bearer your-token-value"
7. 批量删除图片
接口地址: POST /coder/sysPicture/batchDelete
接口描述: 批量删除图片记录和物理文件
是否需要认证: 是
权限要求: system:picture:remove
请求参数:
{
"ids": [1, 2, 3]
}
请求参数说明:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| ids | Long[] | 是 | 图片ID数组 |
响应示例:
{
"status": 200,
"msg": "SUCCESS",
"data": "删除成功",
"traceId": "trace-123456"
}
调用示例:
curl -X POST \
http://localhost:18099/coder/sysPicture/batchDelete \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-value" \
-d '{
"ids": [1, 2, 3]
}'
图片字段说明
基础字段
| 字段名 | 类型 | 说明 | 示例 |
|---|---|---|---|
| pictureId | Long | 图片ID | 1 |
| pictureName | String | 存储图片名 | banner_20240705_001.jpg |
| originalName | String | 原始图片名 | 主页横幅.jpg |
| picturePath | String | 图片相对路径 | /upload/pictures/banner/2024/07/05/banner_20240705_001.jpg |
| pictureUrl | String | 图片访问URL | http://localhost:18099/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg |
| thumbnailUrl | String | 缩略图URL | http://localhost:18099/upload/pictures/banner/2024/07/05/thumb_banner_20240705_001.jpg |
分类字段
| 字段名 | 类型 | 说明 | 示例 |
|---|---|---|---|
| albumName | String | 相册名称 | banner |
| pictureType | String | 图片扩展名 | jpg |
| pictureFormat | String | 图片格式 | JPEG |
| pictureSize | Long | 图片大小(字节) | 2048000 |
尺寸字段
| 字段名 | 类型 | 说明 | 示例 |
|---|---|---|---|
| width | Integer | 图片宽度(像素) | 1920 |
| height | Integer | 图片高度(像素) | 1080 |
状态字段
| 字段名 | 类型 | 说明 | 示例 |
|---|---|---|---|
| pictureStatus | String | 图片状态 | 0-正常 1-删除 |
| isWatermark | String | 是否有水印 | 0-否 1-是 |
| uploadUserId | Long | 上传用户ID | 1 |
| uploadUserName | String | 上传用户名 | admin |
描述字段
| 字段名 | 类型 | 说明 | 示例 |
|---|---|---|---|
| description | String | 图片描述 | 主页横幅图片 |
| tags | String | 图片标签 | 横幅,主页,展示 |
| remark | String | 备注信息 | 网站主页横幅 |
统计字段
| 字段名 | 类型 | 说明 | 示例 |
|---|---|---|---|
| viewCount | Integer | 查看次数 | 100 |
| downloadCount | Integer | 下载次数 | 10 |
数据字典
图片状态 (pictureStatus)
| 值 | 说明 |
|---|---|
| 0 | 正常 |
| 1 | 已删除 |
是否水印 (isWatermark)
| 值 | 说明 |
|---|---|
| 0 | 无水印 |
| 1 | 有水印 |
支持的图片格式
| 格式 | 扩展名 | MIME类型 | 说明 |
|---|---|---|---|
| JPEG | jpg, jpeg | image/jpeg | 有损压缩,适合照片 |
| PNG | png | image/png | 无损压缩,支持透明 |
| GIF | gif | image/gif | 支持动画 |
| WebP | webp | image/webp | 现代格式,压缩率高 |
| BMP | bmp | image/bmp | 位图格式 |
| TIFF | tiff, tif | image/tiff | 高质量图像 |
相册分类
| 相册名称 | 说明 | 用途 |
|---|---|---|
| banner | 横幅图片 | 网站横幅展示 |
| product | 产品图片 | 商品展示 |
| avatar | 头像图片 | 用户头像 |
| gallery | 图库图片 | 相册展示 |
| article | 文章图片 | 文章配图 |
| icon | 图标图片 | 小图标 |
| background | 背景图片 | 页面背景 |
图片处理功能
1. 图片上传处理
@Service
public class PictureUploadService {
/**
* 上传图片
*/
public PictureUploadResult uploadPicture(MultipartFile file, String album) {
// 1. 图片校验
validatePicture(file);
// 2. 生成文件名
String fileName = generatePictureName(file.getOriginalFilename());
// 3. 保存原图
String originalPath = savePicture(file, album, fileName);
// 4. 生成缩略图
String thumbnailPath = generateThumbnail(originalPath, album, fileName);
// 5. 添加水印
if (needWatermark(album)) {
addWatermark(originalPath);
}
// 6. 获取图片信息
BufferedImage image = ImageIO.read(new File(originalPath));
int width = image.getWidth();
int height = image.getHeight();
// 7. 生成访问URL
String pictureUrl = generatePictureUrl(album, fileName);
String thumbnailUrl = generateThumbnailUrl(album, fileName);
// 8. 返回结果
return PictureUploadResult.builder()
.pictureName(fileName)
.originalName(file.getOriginalFilename())
.picturePath(originalPath)
.pictureUrl(pictureUrl)
.thumbnailUrl(thumbnailUrl)
.pictureSize(file.getSize())
.pictureType(getFileExtension(fileName))
.pictureFormat(getImageFormat(file))
.width(width)
.height(height)
.build();
}
/**
* 生成缩略图
*/
private String generateThumbnail(String originalPath, String album, String fileName) {
try {
BufferedImage originalImage = ImageIO.read(new File(originalPath));
// 计算缩略图尺寸
int thumbnailWidth = 200;
int thumbnailHeight = 150;
// 保持宽高比
double ratio = Math.min((double) thumbnailWidth / originalImage.getWidth(),
(double) thumbnailHeight / originalImage.getHeight());
int width = (int) (originalImage.getWidth() * ratio);
int height = (int) (originalImage.getHeight() * ratio);
// 生成缩略图
BufferedImage thumbnailImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = thumbnailImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage(originalImage, 0, 0, width, height, null);
g2d.dispose();
// 保存缩略图
String thumbnailPath = getThumbnailPath(album, fileName);
ImageIO.write(thumbnailImage, "jpg", new File(thumbnailPath));
return thumbnailPath;
} catch (IOException e) {
throw new BusinessException("生成缩略图失败", e);
}
}
/**
* 添加水印
*/
private void addWatermark(String imagePath) {
try {
BufferedImage originalImage = ImageIO.read(new File(imagePath));
Graphics2D g2d = originalImage.createGraphics();
// 设置水印属性
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
g2d.setColor(Color.LIGHT_GRAY);
g2d.setFont(new Font("Arial", Font.BOLD, 20));
// 计算水印位置
FontMetrics fm = g2d.getFontMetrics();
String watermarkText = "© Your Company";
int x = originalImage.getWidth() - fm.stringWidth(watermarkText) - 10;
int y = originalImage.getHeight() - fm.getHeight() + fm.getAscent() - 10;
// 绘制水印
g2d.drawString(watermarkText, x, y);
g2d.dispose();
// 保存带水印的图片
ImageIO.write(originalImage, "jpg", new File(imagePath));
} catch (IOException e) {
throw new BusinessException("添加水印失败", e);
}
}
}
2. 图片压缩
/**
* 图片压缩
*/
public void compressPicture(String inputPath, String outputPath, float quality) {
try {
BufferedImage image = ImageIO.read(new File(inputPath));
// 创建输出流
FileOutputStream fos = new FileOutputStream(outputPath);
// 获取JPEG写入器
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
ImageWriter writer = writers.next();
// 设置输出
ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
writer.setOutput(ios);
// 设置压缩参数
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality); // 压缩质量 0.0-1.0
// 写入图片
writer.write(null, new IIOImage(image, null, null), param);
// 清理资源
ios.close();
fos.close();
writer.dispose();
} catch (IOException e) {
throw new BusinessException("图片压缩失败", e);
}
}
3. 图片格式转换
/**
* 图片格式转换
*/
public void convertPictureFormat(String inputPath, String outputPath, String format) {
try {
BufferedImage image = ImageIO.read(new File(inputPath));
// 如果转换为JPEG,需要处理透明背景
if ("jpg".equalsIgnoreCase(format) || "jpeg".equalsIgnoreCase(format)) {
BufferedImage jpegImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = jpegImage.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, image.getWidth(), image.getHeight());
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
image = jpegImage;
}
// 保存转换后的图片
ImageIO.write(image, format, new File(outputPath));
} catch (IOException e) {
throw new BusinessException("图片格式转换失败", e);
}
}
错误码说明
| 错误码 | 错误信息 | 说明 |
|---|---|---|
| 400 | 图片不能为空 | 上传图片为空 |
| 400 | 图片大小不能超过{size}MB | 图片大小超过限制 |
| 400 | 不支持的图片格式 | 图片格式不支持 |
| 400 | 图片尺寸超过限制 | 图片宽高超过限制 |
| 400 | 图片名称不能为空 | 图片名称为空 |
| 400 | 相册名称不能为空 | 相册名称为空 |
| 400 | 图片不存在 | 图片ID不存在 |
| 400 | 图片已被删除 | 图片状态为已删除 |
| 401 | 当前会话未登录 | 未登录或Token无效 |
| 403 | 权限不足 | 没有相应的操作权限 |
| 500 | 图片上传失败 | 图片保存到磁盘失败 |
| 500 | 缩略图生成失败 | 缩略图生成过程失败 |
| 500 | 水印添加失败 | 水印添加过程失败 |
| 500 | 图片压缩失败 | 图片压缩过程失败 |
| 500 | 图片删除失败 | 物理文件删除失败 |
安全特性
1. 图片验证
- 格式验证: 验证图片格式和MIME类型
- 尺寸验证: 验证图片宽高限制
- 内容验证: 验证图片内容安全性
- 病毒扫描: 对上传图片进行病毒扫描
2. 访问控制
- 权限验证: 验证用户访问权限
- 防盗链: 防止图片被盗链
- 水印保护: 添加水印保护版权
- 下载限制: 限制图片下载次数
3. 存储安全
- 路径安全: 防止路径遍历攻击
- 文件重命名: 重命名避免冲突
- 备份策略: 重要图片定期备份
- 权限设置: 设置合适的文件权限
性能优化
1. 图片处理优化
- 异步处理: 图片压缩和水印添加异步处理
- 批量处理: 支持批量图片处理
- 缓存策略: 缓存处理后的图片
- CDN加速: 使用CDN加速图片访问
2. 存储优化
- 分目录存储: 按相册和日期分目录存储
- 格式优化: 自动选择最优图片格式
- 压缩存储: 自动压缩降低存储空间
- 重复检测: 检测重复图片避免冗余
3. 访问优化
- 懒加载: 图片懒加载技术
- 响应式图片: 根据设备提供不同尺寸
- WebP支持: 支持WebP格式提高性能
- 预加载: 关键图片预加载
使用建议
1. 图片命名规范
- 唯一性: 确保图片名唯一
- 时间戳: 包含时间戳信息
- 分类标识: 包含相册分类信息
- 版本控制: 支持图片版本管理
2. 相册管理
- 分类管理: 按用途分类管理图片
- 权限控制: 不同相册设置不同权限
- 容量限制: 设置相册容量限制
- 定期清理: 定期清理无用图片
3. 图片优化
- 尺寸适配: 根据用途选择合适尺寸
- 格式选择: 根据内容选择最优格式
- 质量平衡: 平衡图片质量和文件大小
- 缓存策略: 设置合适的缓存时间
注意事项
- 图片安全: 严格验证上传图片格式和内容
- 版权保护: 添加水印保护图片版权
- 存储管理: 定期清理无效和重复图片
- 性能考虑: 大图片上传时注意性能影响
- 备份策略: 重要图片需要备份
- 访问控制: 合理设置图片访问权限
- 格式支持: 根据需要支持不同图片格式
- 缩略图: 为提高加载速度生成缩略图
- 压缩处理: 适当压缩减少存储空间
- 监控告警: 监控存储空间和访问异常