260 lines
6.2 KiB
Markdown
260 lines
6.2 KiB
Markdown
|
|
# 海报系统重构方案 (方案 C)
|
|||
|
|
|
|||
|
|
> 完整重构计划,将海报系统改造为 YAML 配置化、模块化的架构
|
|||
|
|
|
|||
|
|
## 一、当前状态 (方案 B 完成后)
|
|||
|
|
|
|||
|
|
### 已完成
|
|||
|
|
- ✅ `domain/poster/poster_service.py` - 轻量服务 (无数据库依赖)
|
|||
|
|
- ✅ `domain/aigc/engines/poster_generate_v2.py` - V2 引擎
|
|||
|
|
- ✅ API 可用: `POST /api/v2/aigc/execute` (engine=poster_generate)
|
|||
|
|
|
|||
|
|
### 遗留问题
|
|||
|
|
| 问题 | 文件 | 说明 |
|
|||
|
|
|-----|------|------|
|
|||
|
|
| 巨型模板文件 | `vibrant_template.py` (78KB) | 难以维护 |
|
|||
|
|
| 模板 bug | `_generate_legacy` | images 参数处理不一致 |
|
|||
|
|
| 配置硬编码 | 模板内部 | 颜色、字体、布局都写死 |
|
|||
|
|
| 旧服务残留 | `api/services/poster.py` | 3000+ 行,依赖已删除模块 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 二、目标架构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
domain/poster/ # 海报核心模块
|
|||
|
|
├── __init__.py
|
|||
|
|
├── poster_service.py # 主服务 (已有)
|
|||
|
|
├── poster_renderer.py # 渲染器 (已有)
|
|||
|
|
├── template_manager.py # 模板管理器 (新增)
|
|||
|
|
└── templates/ # 模板目录 (新增)
|
|||
|
|
├── base.py # 基类
|
|||
|
|
├── vibrant/
|
|||
|
|
│ ├── config.yaml # 模板配置
|
|||
|
|
│ ├── handler.py # 渲染逻辑
|
|||
|
|
│ └── preview.png # 预览图
|
|||
|
|
├── business/
|
|||
|
|
│ ├── config.yaml
|
|||
|
|
│ └── handler.py
|
|||
|
|
└── collage/
|
|||
|
|
├── config.yaml
|
|||
|
|
└── handler.py
|
|||
|
|
|
|||
|
|
prompts/poster/ # 海报 Prompt
|
|||
|
|
├── v1.0.0.yaml # 文案生成 Prompt
|
|||
|
|
└── templates.yaml # 模板元数据索引
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、模板配置 YAML 化
|
|||
|
|
|
|||
|
|
### 示例: `templates/vibrant/config.yaml`
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
meta:
|
|||
|
|
id: vibrant
|
|||
|
|
name: 活力风格
|
|||
|
|
description: 适合景点、活动等充满活力的场景
|
|||
|
|
version: "1.0.0"
|
|||
|
|
preview: preview.png
|
|||
|
|
|
|||
|
|
# 画布配置
|
|||
|
|
canvas:
|
|||
|
|
width: 1350
|
|||
|
|
height: 1800
|
|||
|
|
background: transparent
|
|||
|
|
|
|||
|
|
# 颜色主题
|
|||
|
|
colors:
|
|||
|
|
presets:
|
|||
|
|
ocean_deep:
|
|||
|
|
gradient: [[0, 30, 80], [20, 120, 220]]
|
|||
|
|
sunset_warm:
|
|||
|
|
gradient: [[255, 94, 77], [255, 154, 0]]
|
|||
|
|
cool_mint:
|
|||
|
|
gradient: [[64, 224, 208], [127, 255, 212]]
|
|||
|
|
default: ocean_deep
|
|||
|
|
|
|||
|
|
# 毛玻璃效果
|
|||
|
|
glass_effect:
|
|||
|
|
max_opacity: 240
|
|||
|
|
blur_radius: 22
|
|||
|
|
transition_height: 120
|
|||
|
|
intensity_multiplier: 1.5
|
|||
|
|
|
|||
|
|
# 字体配置
|
|||
|
|
fonts:
|
|||
|
|
title:
|
|||
|
|
path: assets/font/兰亭粗黑简.TTF
|
|||
|
|
size: 72
|
|||
|
|
color: [255, 255, 255]
|
|||
|
|
content:
|
|||
|
|
path: assets/font/兰亭粗黑简.TTF
|
|||
|
|
size: 36
|
|||
|
|
color: [255, 255, 255, 200]
|
|||
|
|
tag:
|
|||
|
|
path: assets/font/兰亭粗黑简.TTF
|
|||
|
|
size: 28
|
|||
|
|
color: [255, 255, 255, 180]
|
|||
|
|
|
|||
|
|
# 布局配置
|
|||
|
|
layout:
|
|||
|
|
title:
|
|||
|
|
position: [50, 1200]
|
|||
|
|
max_width: 1250
|
|||
|
|
content:
|
|||
|
|
position: [50, 1350]
|
|||
|
|
max_width: 1250
|
|||
|
|
line_height: 1.5
|
|||
|
|
tag:
|
|||
|
|
position: [50, 1700]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 四、重构步骤
|
|||
|
|
|
|||
|
|
### Phase 1: 模板管理器 (1天)
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# domain/poster/template_manager.py
|
|||
|
|
|
|||
|
|
class TemplateManager:
|
|||
|
|
"""
|
|||
|
|
模板管理器
|
|||
|
|
- 从 YAML 加载模板配置
|
|||
|
|
- 动态实例化模板处理器
|
|||
|
|
- 支持热重载
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
def __init__(self, templates_dir: str):
|
|||
|
|
self.templates_dir = Path(templates_dir)
|
|||
|
|
self._configs = {}
|
|||
|
|
self._handlers = {}
|
|||
|
|
|
|||
|
|
def load_template(self, template_id: str) -> TemplateConfig:
|
|||
|
|
"""加载模板配置"""
|
|||
|
|
config_path = self.templates_dir / template_id / 'config.yaml'
|
|||
|
|
...
|
|||
|
|
|
|||
|
|
def get_handler(self, template_id: str) -> BaseTemplateHandler:
|
|||
|
|
"""获取模板处理器"""
|
|||
|
|
...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Phase 2: 拆分巨型模板 (2天)
|
|||
|
|
|
|||
|
|
将 `vibrant_template.py` (78KB) 拆分为:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
templates/vibrant/
|
|||
|
|
├── config.yaml # 配置 (从代码中提取)
|
|||
|
|
├── handler.py # 核心渲染逻辑 (~500行)
|
|||
|
|
├── effects.py # 特效函数 (毛玻璃等)
|
|||
|
|
├── text_layout.py # 文字排版
|
|||
|
|
└── color_utils.py # 颜色处理
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Phase 3: 统一模板接口 (1天)
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# domain/poster/templates/base.py
|
|||
|
|
|
|||
|
|
class BaseTemplateHandler(ABC):
|
|||
|
|
"""模板处理器基类"""
|
|||
|
|
|
|||
|
|
def __init__(self, config: TemplateConfig):
|
|||
|
|
self.config = config
|
|||
|
|
|
|||
|
|
@abstractmethod
|
|||
|
|
def render(
|
|||
|
|
self,
|
|||
|
|
image: Image.Image,
|
|||
|
|
content: Dict[str, Any],
|
|||
|
|
**options
|
|||
|
|
) -> RenderResult:
|
|||
|
|
"""渲染海报"""
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
def render_to_base64(self, ...) -> str:
|
|||
|
|
"""渲染并返回 Base64"""
|
|||
|
|
...
|
|||
|
|
|
|||
|
|
def render_to_fabric_json(self, ...) -> dict:
|
|||
|
|
"""渲染并返回 Fabric.js JSON"""
|
|||
|
|
...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Phase 4: 清理旧代码 (0.5天)
|
|||
|
|
|
|||
|
|
- 删除 `api/services/poster.py` (3000+ 行)
|
|||
|
|
- 删除 `poster/poster_generator.py` (旧入口)
|
|||
|
|
- 更新 `utils/__init__.py` 移除无效导入
|
|||
|
|
|
|||
|
|
### Phase 5: 海报 Prompt 管理 (0.5天)
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
# prompts/poster/v1.0.0.yaml
|
|||
|
|
|
|||
|
|
meta:
|
|||
|
|
name: poster_content
|
|||
|
|
version: "1.0.0"
|
|||
|
|
description: "海报文案生成"
|
|||
|
|
|
|||
|
|
system: |
|
|||
|
|
你是一个专业的营销文案策划,擅长创作吸引眼球的海报文案。
|
|||
|
|
|
|||
|
|
user: |
|
|||
|
|
请为以下景区/产品创作海报文案:
|
|||
|
|
|
|||
|
|
## 产品信息
|
|||
|
|
{{ product_info }}
|
|||
|
|
|
|||
|
|
## 要求
|
|||
|
|
- 标题: 10字以内,吸引眼球
|
|||
|
|
- 副标题: 20字以内,突出卖点
|
|||
|
|
- 标签: 3-5个热门标签
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 五、预期收益
|
|||
|
|
|
|||
|
|
| 指标 | 当前 | 重构后 |
|
|||
|
|
|-----|------|--------|
|
|||
|
|
| 模板文件大小 | 78KB (单文件) | ~5KB (配置) + ~500行 (代码) |
|
|||
|
|
| 新增模板难度 | 需要写 Python | 只需写 YAML 配置 |
|
|||
|
|
| 配置修改 | 改代码重启 | 改 YAML 热重载 |
|
|||
|
|
| 代码可维护性 | 低 | 高 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 六、时间估算
|
|||
|
|
|
|||
|
|
| 阶段 | 工作量 | 优先级 |
|
|||
|
|
|-----|--------|--------|
|
|||
|
|
| Phase 1: 模板管理器 | 1天 | P1 |
|
|||
|
|
| Phase 2: 拆分模板 | 2天 | P1 |
|
|||
|
|
| Phase 3: 统一接口 | 1天 | P1 |
|
|||
|
|
| Phase 4: 清理旧代码 | 0.5天 | P2 |
|
|||
|
|
| Phase 5: Prompt 管理 | 0.5天 | P2 |
|
|||
|
|
| **总计** | **5天** | |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、风险与注意事项
|
|||
|
|
|
|||
|
|
1. **向后兼容**: Java 端调用接口不变
|
|||
|
|
2. **模板效果**: 重构后视觉效果需与原版一致
|
|||
|
|
3. **性能**: 配置加载需要缓存,避免每次渲染都读文件
|
|||
|
|
4. **测试**: 需要对比测试,确保输出一致
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 八、下一步行动
|
|||
|
|
|
|||
|
|
1. [ ] 确认是否立即开始方案 C
|
|||
|
|
2. [ ] 或先处理热点爬虫需求
|
|||
|
|
3. [ ] 或先完善其他功能
|