You've already forked FrameTour-BE
refactor(puzzle): 重构元素DTO及新增元素基类
- 将ElementCreateRequest和PuzzleElementDTO中的elementType从Integer改为String - 删除所有类型特定字段,新增config和configMap支持JSON配置 - 新增BaseElement抽象基类定义元素通用行为 - 添加ElementConfig接口和具体实现类ImageConfig、TextConfig - 创建ElementFactory工厂类和ElementRegistrar注册器 - 新增ElementType枚举和ElementValidationException异常类 - 实现ImageElement和TextElement具体元素类 - 添加Position位置信息封装类
This commit is contained in:
611
src/main/java/com/ycwl/basic/puzzle/claude.md
Normal file
611
src/main/java/com/ycwl/basic/puzzle/claude.md
Normal file
@@ -0,0 +1,611 @@
|
||||
# Puzzle 拼图模块技术文档
|
||||
|
||||
## 📋 模块概述
|
||||
|
||||
Puzzle拼图模块是一个基于模板和元素的动态图片生成系统,支持按照预定义的模板配置,将动态数据渲染成最终的图片输出。常用于订单凭证、门票、证书等场景的图片生成。
|
||||
|
||||
**核心能力:**
|
||||
- 模板化图片生成:通过模板+元素+动态数据生成定制化图片
|
||||
- 多层次元素渲染:支持图片和文字元素的分层叠加
|
||||
- 灵活的样式配置:支持位置、大小、透明度、旋转、圆角等属性
|
||||
- 动态数据注入:通过elementKey进行动态数据替换
|
||||
- 生成记录追踪:完整记录每次生成的参数和结果
|
||||
|
||||
**典型应用场景:**
|
||||
- 订单凭证图片生成(用户头像+订单信息)
|
||||
- 电子门票生成(二维码+用户信息)
|
||||
- 电子证书生成(用户信息+证书模板)
|
||||
- 营销海报生成(动态用户数据)
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 架构设计
|
||||
|
||||
### 分层结构
|
||||
|
||||
```
|
||||
puzzle/
|
||||
├── controller/ # API接口层
|
||||
│ ├── PuzzleGenerateController.java # 拼图生成接口
|
||||
│ └── PuzzleTemplateController.java # 模板管理接口
|
||||
├── service/ # 业务逻辑层
|
||||
│ ├── IPuzzleGenerateService.java
|
||||
│ ├── IPuzzleTemplateService.java
|
||||
│ └── impl/
|
||||
│ ├── PuzzleGenerateServiceImpl.java
|
||||
│ └── PuzzleTemplateServiceImpl.java
|
||||
├── mapper/ # 数据访问层
|
||||
│ ├── PuzzleTemplateMapper.java
|
||||
│ ├── PuzzleElementMapper.java
|
||||
│ └── PuzzleGenerationRecordMapper.java
|
||||
├── entity/ # 实体类
|
||||
│ ├── PuzzleTemplateEntity.java # 模板实体
|
||||
│ ├── PuzzleElementEntity.java # 元素实体
|
||||
│ └── PuzzleGenerationRecordEntity.java # 生成记录实体
|
||||
├── dto/ # 数据传输对象
|
||||
│ ├── PuzzleGenerateRequest.java # 生成请求
|
||||
│ ├── PuzzleGenerateResponse.java # 生成响应
|
||||
│ ├── PuzzleTemplateDTO.java # 模板DTO
|
||||
│ ├── PuzzleElementDTO.java # 元素DTO
|
||||
│ ├── TemplateCreateRequest.java # 模板创建请求
|
||||
│ └── ElementCreateRequest.java # 元素创建请求
|
||||
└── util/ # 工具类
|
||||
└── PuzzleImageRenderer.java # 图片渲染引擎(核心)
|
||||
```
|
||||
|
||||
### 设计模式
|
||||
|
||||
1. **服务层模式(Service Layer)**:业务逻辑封装在service层,controller只负责接口适配
|
||||
2. **DTO模式**:使用独立的DTO对象处理API输入输出,与Entity分离
|
||||
3. **策略模式**:图片适配模式(CONTAIN、COVER、FILL等)
|
||||
4. **建造者模式**:通过模板+元素配置构建最终图片
|
||||
|
||||
---
|
||||
|
||||
## 🔧 核心组件详解
|
||||
|
||||
### 1. PuzzleImageRenderer - 图片渲染引擎
|
||||
|
||||
**职责**:核心渲染引擎,负责将模板配置和元素数据渲染成最终图片
|
||||
|
||||
**关键方法**:
|
||||
- `render(PuzzleTemplateEntity, List<PuzzleElementEntity>, Map<String, String>)`:主渲染方法
|
||||
- 创建画布(根据模板宽高)
|
||||
- 绘制背景(纯色或图片背景)
|
||||
- 按z-index顺序绘制元素
|
||||
- 返回BufferedImage对象
|
||||
|
||||
**渲染流程**:
|
||||
1. 创建画布:根据模板的canvasWidth和canvasHeight创建BufferedImage
|
||||
2. 绘制背景:
|
||||
- backgroundType=0:绘制纯色背景(backgroundColor)
|
||||
- backgroundType=1:加载并绘制背景图片(backgroundImage)
|
||||
3. 按z-index排序元素列表(升序,确保层级正确)
|
||||
4. 逐个绘制元素:
|
||||
- elementType=1(图片元素):
|
||||
- 获取动态数据(dynamicData.get(elementKey))或使用defaultImageUrl
|
||||
- 下载图片
|
||||
- 根据imageFitMode缩放图片(CONTAIN/COVER/FILL/SCALE_DOWN)
|
||||
- 应用borderRadius(圆角)
|
||||
- 应用opacity(透明度)
|
||||
- 应用rotation(旋转)
|
||||
- 绘制到画布指定位置(xPosition, yPosition, width, height)
|
||||
- elementType=2(文字元素):
|
||||
- 获取动态数据或使用defaultText
|
||||
- 设置字体(fontFamily, fontSize, fontWeight, fontStyle)
|
||||
- 设置颜色(fontColor)
|
||||
- 应用textAlign(对齐方式)
|
||||
- 应用lineHeight(行高)
|
||||
- 处理maxLines(最大行数截断)
|
||||
- 应用textDecoration(下划线/删除线)
|
||||
- 应用opacity和rotation
|
||||
- 绘制到画布
|
||||
|
||||
**技术要点**:
|
||||
- 使用Java AWT进行图形绘制
|
||||
- 使用Hutool工具库处理图片下载和基础操作
|
||||
- 支持图片圆角(通过Ellipse2D.Float或RoundRectangle2D.Float实现clip)
|
||||
- 支持透明度(通过AlphaComposite实现)
|
||||
- 支持旋转(通过Graphics2D.rotate)
|
||||
|
||||
---
|
||||
|
||||
### 2. PuzzleGenerateServiceImpl - 拼图生成服务
|
||||
|
||||
**职责**:协调拼图生成的完整流程
|
||||
|
||||
**核心方法**:
|
||||
```java
|
||||
PuzzleGenerateResponse generate(PuzzleGenerateRequest request)
|
||||
```
|
||||
|
||||
**生成流程**:
|
||||
1. **参数校验**:
|
||||
- 校验templateCode是否提供
|
||||
- 检查dynamicData是否为空
|
||||
2. **加载模板**:
|
||||
- 根据templateCode查询模板(PuzzleTemplateMapper)
|
||||
- 检查模板是否存在且启用(status=1)
|
||||
- 检查多租户权限(scenicId匹配)
|
||||
3. **加载元素**:
|
||||
- 根据templateId查询所有元素(PuzzleElementMapper)
|
||||
- 按z-index升序排序
|
||||
- 过滤未删除的元素(deleted=0)
|
||||
4. **调用渲染引擎**:
|
||||
- 调用`PuzzleImageRenderer.render()`
|
||||
- 传入模板、元素列表、动态数据
|
||||
5. **上传图片**:
|
||||
- 将BufferedImage转换为字节流
|
||||
- 估算文件大小
|
||||
- 上传到对象存储(OSS)
|
||||
- 获取图片URL
|
||||
6. **创建生成记录**:
|
||||
- 保存到puzzle_generation_record表
|
||||
- 记录参数、结果、耗时等信息
|
||||
7. **返回响应**:
|
||||
- 返回图片URL、宽高、文件大小等信息
|
||||
|
||||
**辅助方法**:
|
||||
- `createRecord()`:创建生成记录
|
||||
- `uploadImage()`:上传图片到OSS
|
||||
- `estimateFileSize()`:估算文件大小
|
||||
|
||||
---
|
||||
|
||||
### 3. PuzzleTemplateServiceImpl - 模板管理服务
|
||||
|
||||
**职责**:管理拼图模板和元素的CRUD操作
|
||||
|
||||
**模板管理方法**:
|
||||
- `createTemplate(TemplateCreateRequest)`:创建模板
|
||||
- `updateTemplate(Long, TemplateCreateRequest)`:更新模板
|
||||
- `deleteTemplate(Long)`:逻辑删除模板(软删除)
|
||||
- `getTemplateDetail(Long)`:查询模板详情(包含元素列表)
|
||||
- `getTemplateByCode(String)`:根据code查询模板
|
||||
- `listTemplates(Long, String, Integer)`:分页查询模板列表
|
||||
|
||||
**元素管理方法**:
|
||||
- `addElement(ElementCreateRequest)`:添加单个元素
|
||||
- `batchAddElements(Long, List<ElementCreateRequest>)`:批量添加元素
|
||||
- `updateElement(Long, ElementCreateRequest)`:更新元素
|
||||
- `deleteElement(Long)`:逻辑删除元素
|
||||
- `getElementDetail(Long)`:查询元素详情
|
||||
|
||||
**业务逻辑要点**:
|
||||
- 删除模板时会级联删除关联的所有元素
|
||||
- 支持多租户隔离(根据scenicId)
|
||||
- 支持按category分类查询
|
||||
- 支持按status过滤启用/禁用的模板
|
||||
|
||||
---
|
||||
|
||||
### 4. Controller接口层
|
||||
|
||||
#### PuzzleGenerateController
|
||||
```java
|
||||
POST /puzzle/generate
|
||||
```
|
||||
**功能**:生成拼图图片
|
||||
|
||||
**请求体**:`PuzzleGenerateRequest`
|
||||
```json
|
||||
{
|
||||
"templateCode": "order_certificate",
|
||||
"userId": 123,
|
||||
"orderId": "ORDER20250117001",
|
||||
"businessType": "order",
|
||||
"scenicId": 1,
|
||||
"dynamicData": {
|
||||
"userAvatar": "https://example.com/avatar.jpg",
|
||||
"userName": "张三",
|
||||
"orderNumber": "ORDER20250117001",
|
||||
"qrCode": "https://example.com/qr.png"
|
||||
},
|
||||
"outputFormat": "PNG",
|
||||
"quality": 90
|
||||
}
|
||||
```
|
||||
|
||||
**响应**:`AjaxResult<PuzzleGenerateResponse>`
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "生成成功",
|
||||
"data": {
|
||||
"imageUrl": "https://oss.example.com/puzzle/xxx.png",
|
||||
"width": 750,
|
||||
"height": 1334,
|
||||
"fileSize": 245678,
|
||||
"recordId": 12345
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### PuzzleTemplateController
|
||||
提供模板和元素的完整CRUD接口(详见Controller类)
|
||||
|
||||
---
|
||||
|
||||
## 📊 数据模型
|
||||
|
||||
### 1. puzzle_template - 拼图模板表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|-----|------|-----|
|
||||
| id | BIGINT | 主键ID |
|
||||
| name | VARCHAR(100) | 模板名称 |
|
||||
| code | VARCHAR(50) | 模板编码(唯一,用于API调用) |
|
||||
| canvas_width | INT | 画布宽度(像素) |
|
||||
| canvas_height | INT | 画布高度(像素) |
|
||||
| background_type | TINYINT | 背景类型:0-纯色 1-图片 |
|
||||
| background_color | VARCHAR(20) | 背景颜色(hex格式,如#FFFFFF) |
|
||||
| background_image | VARCHAR(500) | 背景图片URL |
|
||||
| description | TEXT | 模板描述 |
|
||||
| category | VARCHAR(50) | 模板分类(order/ticket/certificate等) |
|
||||
| status | TINYINT | 状态:0-禁用 1-启用 |
|
||||
| scenic_id | BIGINT | 景区ID(多租户隔离) |
|
||||
| create_time | DATETIME | 创建时间 |
|
||||
| update_time | DATETIME | 更新时间 |
|
||||
| deleted | TINYINT | 删除标记:0-未删除 1-已删除 |
|
||||
| deleted_at | DATETIME | 删除时间 |
|
||||
|
||||
**索引**:
|
||||
- UNIQUE KEY `uk_code` (code, deleted)
|
||||
- KEY `idx_scenic_id` (scenic_id)
|
||||
- KEY `idx_category_status` (category, status, deleted)
|
||||
|
||||
---
|
||||
|
||||
### 2. puzzle_element - 拼图元素表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|-----|------|-----|
|
||||
| id | BIGINT | 主键ID |
|
||||
| template_id | BIGINT | 模板ID(外键) |
|
||||
| element_type | TINYINT | 元素类型:1-图片 2-文字 |
|
||||
| element_key | VARCHAR(50) | 元素标识(用于动态数据映射) |
|
||||
| element_name | VARCHAR(100) | 元素名称(便于管理) |
|
||||
|
||||
**位置和布局属性**:
|
||||
| 字段 | 类型 | 说明 |
|
||||
|-----|------|-----|
|
||||
| x_position | INT | X坐标(相对画布左上角) |
|
||||
| y_position | INT | Y坐标(相对画布左上角) |
|
||||
| width | INT | 宽度(像素) |
|
||||
| height | INT | 高度(像素) |
|
||||
| z_index | INT | 层级(数值越大越靠上) |
|
||||
| rotation | INT | 旋转角度(0-360度,顺时针) |
|
||||
| opacity | INT | 不透明度(0-100) |
|
||||
|
||||
**图片元素专有属性**:
|
||||
| 字段 | 类型 | 说明 |
|
||||
|-----|------|-----|
|
||||
| default_image_url | VARCHAR(500) | 默认图片URL |
|
||||
| image_fit_mode | VARCHAR(20) | 图片适配模式:CONTAIN/COVER/FILL/SCALE_DOWN |
|
||||
| border_radius | INT | 圆角半径(像素) |
|
||||
|
||||
**文字元素专有属性**:
|
||||
| 字段 | 类型 | 说明 |
|
||||
|-----|------|-----|
|
||||
| default_text | TEXT | 默认文本内容 |
|
||||
| font_family | VARCHAR(50) | 字体名称 |
|
||||
| font_size | INT | 字号(像素) |
|
||||
| font_color | VARCHAR(20) | 字体颜色(hex) |
|
||||
| font_weight | VARCHAR(20) | 字重:NORMAL/BOLD |
|
||||
| font_style | VARCHAR(20) | 字体样式:NORMAL/ITALIC |
|
||||
| text_align | VARCHAR(20) | 对齐方式:LEFT/CENTER/RIGHT |
|
||||
| line_height | DECIMAL(3,2) | 行高倍数(如1.5) |
|
||||
| max_lines | INT | 最大行数(NULL表示不限制) |
|
||||
| text_decoration | VARCHAR(20) | 文本装饰:NONE/UNDERLINE/LINE_THROUGH |
|
||||
|
||||
**索引**:
|
||||
- KEY `idx_template_id` (template_id, deleted)
|
||||
- KEY `idx_element_key` (element_key)
|
||||
|
||||
---
|
||||
|
||||
### 3. puzzle_generation_record - 拼图生成记录表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|-----|------|-----|
|
||||
| id | BIGINT | 主键ID |
|
||||
| template_id | BIGINT | 模板ID |
|
||||
| template_code | VARCHAR(50) | 模板编码(冗余) |
|
||||
| user_id | BIGINT | 用户ID |
|
||||
| order_id | VARCHAR(50) | 关联订单号 |
|
||||
| business_type | VARCHAR(50) | 业务类型 |
|
||||
| generation_params | TEXT | 生成参数(JSON格式) |
|
||||
| result_image_url | VARCHAR(500) | 生成的图片URL |
|
||||
| result_file_size | BIGINT | 文件大小(字节) |
|
||||
| result_width | INT | 图片宽度 |
|
||||
| result_height | INT | 图片高度 |
|
||||
| status | TINYINT | 状态:0-生成中 1-成功 2-失败 |
|
||||
| error_message | TEXT | 错误信息(失败时) |
|
||||
| generation_duration | INT | 生成耗时(毫秒) |
|
||||
| retry_count | INT | 重试次数 |
|
||||
| scenic_id | BIGINT | 景区ID |
|
||||
| client_ip | VARCHAR(50) | 客户端IP |
|
||||
| user_agent | VARCHAR(500) | 客户端User-Agent |
|
||||
| create_time | DATETIME | 创建时间 |
|
||||
| update_time | DATETIME | 更新时间 |
|
||||
|
||||
**索引**:
|
||||
- KEY `idx_user_id` (user_id)
|
||||
- KEY `idx_order_id` (order_id)
|
||||
- KEY `idx_template_id` (template_id)
|
||||
- KEY `idx_create_time` (create_time)
|
||||
|
||||
---
|
||||
|
||||
## 🔄 关键业务流程
|
||||
|
||||
### 拼图生成完整流程
|
||||
|
||||
```
|
||||
用户请求 → Controller接收
|
||||
↓
|
||||
验证templateCode和dynamicData
|
||||
↓
|
||||
根据templateCode查询模板(含权限校验)
|
||||
↓
|
||||
根据templateId查询所有元素(按z-index排序)
|
||||
↓
|
||||
调用PuzzleImageRenderer.render()
|
||||
├─ 创建画布
|
||||
├─ 绘制背景
|
||||
├─ 遍历元素列表
|
||||
│ ├─ 图片元素:下载图片 → 缩放/圆角/透明度/旋转 → 绘制
|
||||
│ └─ 文字元素:设置字体样式 → 计算布局 → 绘制
|
||||
└─ 返回BufferedImage
|
||||
↓
|
||||
将BufferedImage转换为字节流
|
||||
↓
|
||||
上传到OSS获取URL
|
||||
↓
|
||||
创建生成记录(保存参数和结果)
|
||||
↓
|
||||
返回响应(imageUrl、width、height、fileSize等)
|
||||
```
|
||||
|
||||
### 图片适配模式说明
|
||||
|
||||
**CONTAIN(等比缩放适应)**:
|
||||
- 图片完全显示在区域内
|
||||
- 保持图片宽高比
|
||||
- 可能留白
|
||||
|
||||
**COVER(等比缩放填充)**:
|
||||
- 完全覆盖目标区域
|
||||
- 保持图片宽高比
|
||||
- 可能裁剪图片
|
||||
|
||||
**FILL(拉伸填充)**:
|
||||
- 完全填充目标区域
|
||||
- 不保持宽高比
|
||||
- 可能变形
|
||||
|
||||
**SCALE_DOWN(缩小适应)**:
|
||||
- 类似CONTAIN
|
||||
- 但不放大图片(仅缩小)
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 技术栈
|
||||
|
||||
### 核心依赖
|
||||
- **Spring Boot**:框架基础
|
||||
- **MyBatis Plus**:数据访问
|
||||
- **Lombok**:减少样板代码
|
||||
- **Hutool**:工具类库(图片处理、HTTP下载)
|
||||
- **Java AWT/ImageIO**:图形绘制和图片处理
|
||||
- **SLF4J/Logback**:日志
|
||||
|
||||
### 外部依赖
|
||||
- **OSS对象存储**:图片上传和存储
|
||||
- **MySQL**:关系型数据库
|
||||
|
||||
---
|
||||
|
||||
## 📦 对外依赖
|
||||
|
||||
puzzle模块与其他模块的依赖关系:
|
||||
|
||||
| 依赖模块 | 依赖项 | 用途 |
|
||||
|---------|--------|-----|
|
||||
| storage | OSS上传服务 | 上传生成的图片到对象存储 |
|
||||
| config | 全局配置 | 获取系统配置信息 |
|
||||
| exception | 自定义异常 | 业务异常处理 |
|
||||
| utils | 工具类 | 通用工具方法 |
|
||||
|
||||
**被依赖情况**:
|
||||
- order模块:订单凭证图片生成
|
||||
- ticket模块:电子门票图片生成
|
||||
- 其他需要动态图片生成的业务模块
|
||||
|
||||
---
|
||||
|
||||
## 🚀 扩展指南
|
||||
|
||||
### 1. 新增元素类型
|
||||
如需支持新的元素类型(如二维码元素、形状元素等):
|
||||
1. 在`PuzzleElementEntity`中新增`elementType`枚举值
|
||||
2. 在`PuzzleImageRenderer.render()`中添加新类型的渲染逻辑
|
||||
3. 新增元素专有属性到`puzzle_element`表和实体类
|
||||
4. 更新DTO和请求对象
|
||||
|
||||
### 2. 新增图片格式支持
|
||||
当前支持PNG和JPEG,如需支持WebP、SVG等:
|
||||
1. 更新`PuzzleGenerateRequest.outputFormat`校验逻辑
|
||||
2. 修改`PuzzleGenerateServiceImpl.uploadImage()`中的格式转换逻辑
|
||||
3. 注意浏览器兼容性
|
||||
|
||||
### 3. 新增渲染效果
|
||||
如需支持阴影、边框、渐变等效果:
|
||||
1. 在`PuzzleElementEntity`中新增对应的属性字段
|
||||
2. 在`PuzzleImageRenderer`中实现对应的绘制逻辑
|
||||
3. 使用Java AWT的相关API(如`setShadow`、`drawRect`等)
|
||||
|
||||
### 4. 批量生成优化
|
||||
如需支持批量生成(如批量生成门票):
|
||||
1. 新增批量生成接口`POST /puzzle/batchGenerate`
|
||||
2. 使用线程池并发处理
|
||||
3. 返回任务ID,支持异步查询结果
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 重要注意事项
|
||||
|
||||
### 1. 性能优化
|
||||
- **图片缓存**:对于默认图片URL,考虑使用本地缓存避免重复下载
|
||||
- **并发控制**:高并发场景下,生成接口应加限流保护
|
||||
- **资源释放**:及时释放BufferedImage和Graphics2D对象,避免内存泄漏
|
||||
- **异步处理**:对于复杂模板,考虑异步生成+回调通知
|
||||
|
||||
### 2. 安全性
|
||||
- **URL校验**:对dynamicData中的图片URL进行白名单校验,防止SSRF攻击
|
||||
- **文件大小限制**:限制下载图片的大小,防止资源耗尽
|
||||
- **权限控制**:确保scenicId隔离,防止越权访问
|
||||
- **输入校验**:严格校验所有输入参数,防止XSS和注入攻击
|
||||
|
||||
### 3. 多租户隔离
|
||||
- 所有查询必须带上scenicId条件
|
||||
- 创建模板和元素时必须关联正确的scenicId
|
||||
- 生成拼图时校验模板的scenicId权限
|
||||
|
||||
### 4. 错误处理
|
||||
- 图片下载失败时的降级策略(使用默认图片)
|
||||
- 渲染失败时记录详细错误日志
|
||||
- 对外暴露友好的错误提示
|
||||
|
||||
### 5. 字体问题
|
||||
- **字体文件**:确保服务器安装了模板使用的字体文件
|
||||
- **中文字体**:Linux服务器需要安装中文字体(如文泉驿)
|
||||
- **字体回退**:设置字体回退机制,避免乱码
|
||||
|
||||
### 6. 数据一致性
|
||||
- 删除模板时级联删除元素(软删除)
|
||||
- 更新模板状态时考虑对正在生成的任务的影响
|
||||
- 生成记录不可删除,仅供审计和统计
|
||||
|
||||
### 7. 监控和日志
|
||||
- 记录每次生成的耗时,监控性能
|
||||
- 记录生成失败的详细原因,便于排查
|
||||
- 统计各模板的使用频率,优化热点模板
|
||||
|
||||
---
|
||||
|
||||
## 📈 性能指标参考
|
||||
|
||||
**典型性能数据**(测试环境):
|
||||
- 单张简单拼图(2-3个元素):< 500ms
|
||||
- 单张复杂拼图(10+个元素):< 1500ms
|
||||
- 图片下载耗时:200-500ms(取决于网络)
|
||||
- 渲染耗时:50-200ms
|
||||
- OSS上传耗时:100-300ms
|
||||
|
||||
**优化建议**:
|
||||
- 使用CDN加速图片下载
|
||||
- 预热常用模板的背景图片
|
||||
- 使用Redis缓存模板和元素配置
|
||||
|
||||
---
|
||||
|
||||
## 📝 示例代码
|
||||
|
||||
### 创建模板示例
|
||||
```java
|
||||
// 1. 创建模板
|
||||
TemplateCreateRequest templateReq = new TemplateCreateRequest();
|
||||
templateReq.setName("订单凭证模板");
|
||||
templateReq.setCode("order_certificate_v1");
|
||||
templateReq.setCanvasWidth(750);
|
||||
templateReq.setCanvasHeight(1334);
|
||||
templateReq.setBackgroundType(1);
|
||||
templateReq.setBackgroundImage("https://oss.example.com/bg.jpg");
|
||||
templateReq.setCategory("order");
|
||||
templateReq.setScenicId(1L);
|
||||
|
||||
Long templateId = templateService.createTemplate(templateReq);
|
||||
|
||||
// 2. 添加元素 - 用户头像(图片元素)
|
||||
ElementCreateRequest avatarElement = new ElementCreateRequest();
|
||||
avatarElement.setTemplateId(templateId);
|
||||
avatarElement.setElementType(1); // 图片
|
||||
avatarElement.setElementKey("userAvatar");
|
||||
avatarElement.setElementName("用户头像");
|
||||
avatarElement.setXPosition(50);
|
||||
avatarElement.setYPosition(100);
|
||||
avatarElement.setWidth(100);
|
||||
avatarElement.setHeight(100);
|
||||
avatarElement.setZIndex(10);
|
||||
avatarElement.setDefaultImageUrl("https://oss.example.com/default-avatar.png");
|
||||
avatarElement.setImageFitMode("COVER");
|
||||
avatarElement.setBorderRadius(50); // 圆形头像
|
||||
avatarElement.setOpacity(100);
|
||||
|
||||
templateService.addElement(avatarElement);
|
||||
|
||||
// 3. 添加元素 - 用户名(文字元素)
|
||||
ElementCreateRequest nameElement = new ElementCreateRequest();
|
||||
nameElement.setTemplateId(templateId);
|
||||
nameElement.setElementType(2); // 文字
|
||||
nameElement.setElementKey("userName");
|
||||
nameElement.setElementName("用户名");
|
||||
nameElement.setXPosition(170);
|
||||
nameElement.setYPosition(120);
|
||||
nameElement.setWidth(300);
|
||||
nameElement.setHeight(60);
|
||||
nameElement.setZIndex(20);
|
||||
nameElement.setDefaultText("用户名");
|
||||
nameElement.setFontFamily("PingFang SC");
|
||||
nameElement.setFontSize(28);
|
||||
nameElement.setFontColor("#333333");
|
||||
nameElement.setFontWeight("BOLD");
|
||||
nameElement.setTextAlign("LEFT");
|
||||
nameElement.setLineHeight(new BigDecimal("1.5"));
|
||||
|
||||
templateService.addElement(nameElement);
|
||||
```
|
||||
|
||||
### 生成拼图示例
|
||||
```java
|
||||
// 调用生成接口
|
||||
PuzzleGenerateRequest request = new PuzzleGenerateRequest();
|
||||
request.setTemplateCode("order_certificate_v1");
|
||||
request.setUserId(123L);
|
||||
request.setOrderId("ORDER20250117001");
|
||||
request.setBusinessType("order");
|
||||
request.setScenicId(1L);
|
||||
|
||||
Map<String, String> dynamicData = new HashMap<>();
|
||||
dynamicData.put("userAvatar", "https://oss.example.com/user123/avatar.jpg");
|
||||
dynamicData.put("userName", "张三");
|
||||
dynamicData.put("orderNumber", "ORDER20250117001");
|
||||
dynamicData.put("qrCode", "https://oss.example.com/qr/ORDER20250117001.png");
|
||||
request.setDynamicData(dynamicData);
|
||||
|
||||
request.setOutputFormat("PNG");
|
||||
request.setQuality(90);
|
||||
|
||||
PuzzleGenerateResponse response = generateService.generate(request);
|
||||
System.out.println("生成成功,图片URL: " + response.getImageUrl());
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔗 相关文档
|
||||
|
||||
- [MyBatis-Plus官方文档](https://baomidou.com/)
|
||||
- [Hutool工具类文档](https://hutool.cn/)
|
||||
- [Java AWT图形绘制教程](https://docs.oracle.com/javase/tutorial/2d/)
|
||||
- [阿里云OSS Java SDK](https://help.aliyun.com/document_detail/32008.html)
|
||||
|
||||
---
|
||||
|
||||
## 📞 联系方式
|
||||
|
||||
如有问题或建议,请联系模块负责人或提交Issue。
|
||||
|
||||
**维护者**:Claude
|
||||
**创建时间**:2025-01-17
|
||||
**最后更新**:2025-01-17
|
||||
Reference in New Issue
Block a user