coder-thin-template-backend/api/system/图片管理API.md
Leo 19d3eccb5b chore: 初始化项目基础配置
- 添加Maven父POM配置,定义项目依赖版本
- 配置项目模块结构
- 添加.gitignore规则
- 添加项目文档和开发指南
2025-10-08 02:00:43 +08:00

871 lines
24 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 图片管理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 |
**响应示例**:
```json
{
"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"
}
```
**调用示例**:
```bash
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外
**响应示例**:
```json
{
"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"
}
```
**调用示例**:
```bash
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 |
**响应示例**:
```json
{
"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"
}
```
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/coder/sysPicture/getById/1 \
-H "Authorization: Bearer your-token-value"
```
---
### 4. 新增图片记录
**接口地址**: `POST /coder/sysPicture/add`
**接口描述**: 新增系统图片记录
**是否需要认证**: 是
**权限要求**: `system:picture:upload`
**请求参数**:
```json
{
"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字符 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "新增成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
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`
**请求参数**:
```json
{
"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 |
| 其他参数 | - | - | 同新增图片记录 | - |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "修改成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
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 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "删除成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysPicture/deleteById/1 \
-H "Authorization: Bearer your-token-value"
```
---
### 7. 批量删除图片
**接口地址**: `POST /coder/sysPicture/batchDelete`
**接口描述**: 批量删除图片记录和物理文件
**是否需要认证**: 是
**权限要求**: `system:picture:remove`
**请求参数**:
```json
{
"ids": [1, 2, 3]
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| ids | Long[] | 是 | 图片ID数组 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "删除成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
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. 图片上传处理
```java
@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. 图片压缩
```java
/**
* 图片压缩
*/
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. 图片格式转换
```java
/**
* 图片格式转换
*/
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. 图片优化
- **尺寸适配**: 根据用途选择合适尺寸
- **格式选择**: 根据内容选择最优格式
- **质量平衡**: 平衡图片质量和文件大小
- **缓存策略**: 设置合适的缓存时间
---
## 注意事项
1. **图片安全**: 严格验证上传图片格式和内容
2. **版权保护**: 添加水印保护图片版权
3. **存储管理**: 定期清理无效和重复图片
4. **性能考虑**: 大图片上传时注意性能影响
5. **备份策略**: 重要图片需要备份
6. **访问控制**: 合理设置图片访问权限
7. **格式支持**: 根据需要支持不同图片格式
8. **缩略图**: 为提高加载速度生成缩略图
9. **压缩处理**: 适当压缩减少存储空间
10. **监控告警**: 监控存储空间和访问异常