390 lines
10 KiB
Markdown
390 lines
10 KiB
Markdown
# 系统设计文档
|
||
|
||
## 1. 系统架构
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 小票打印系统 (本地服务) │
|
||
├─────────────────────────────────────────────────────────┤
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌───────────┐ │
|
||
│ │ Web 配置页 │◄──►│ 模板引擎 │◄──►│ 打印机 │ │
|
||
│ │ (Vue/React) │ │ (渲染/ESC-POS)│ │ (WiFi ESC)│ │
|
||
│ └──────────────┘ └──────────────┘ └───────────┘ │
|
||
│ ▲ │
|
||
│ │ REST API │
|
||
│ ▼ │
|
||
│ ┌──────────────┐ │
|
||
│ │ 外部调用端 │ ← 脚本、IFTTT、快捷指令等 │
|
||
│ │ (curl/HTTP) │ │
|
||
│ └──────────────┘ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 数据流
|
||
|
||
1. **配置阶段**: Web 页创建/编辑模板 → 保存为 YAML 配置
|
||
2. **调用阶段**: POST 数据到 `/api/print/:templateId` → 模板引擎渲染 → 生成 ESC/POS 指令 → 发送到打印机
|
||
|
||
## 2. 模板系统
|
||
|
||
### 2.1 模板结构
|
||
|
||
```yaml
|
||
# 模板元信息
|
||
name: "每日待办"
|
||
id: "daily-todo"
|
||
width: 80mm
|
||
description: "打印今日待办事项列表"
|
||
|
||
# 页面设置
|
||
page:
|
||
marginTop: 2
|
||
marginBottom: 3
|
||
|
||
# 默认样式
|
||
defaults:
|
||
fontSize: normal
|
||
lineHeight: 1.0
|
||
marginBottom: 0
|
||
|
||
# 内容块
|
||
blocks:
|
||
# 文本块
|
||
- type: text
|
||
content: "📋 {{date}} 待办"
|
||
align: center
|
||
fontSize: large
|
||
bold: true
|
||
marginBottom: 1
|
||
|
||
# 分隔线
|
||
- type: divider
|
||
char: "="
|
||
marginBottom: 1
|
||
|
||
# 列表循环
|
||
- type: list
|
||
data: "{{tasks}}"
|
||
itemTemplate:
|
||
- type: text
|
||
content: "[{{status}}] {{title}}"
|
||
fontSize: normal
|
||
marginBottom: 0
|
||
|
||
# 多列行
|
||
- type: row
|
||
marginBottom: 1
|
||
columns:
|
||
- content: "{{leftText}}"
|
||
align: left
|
||
width: 50%
|
||
bold: true
|
||
- content: "{{rightText}}"
|
||
align: right
|
||
width: 50%
|
||
|
||
# 表格
|
||
- type: table
|
||
marginBottom: 1
|
||
columns:
|
||
- header: "商品"
|
||
align: left
|
||
width: 50%
|
||
- header: "数量"
|
||
align: center
|
||
width: 25%
|
||
- header: "金额"
|
||
align: right
|
||
width: 25%
|
||
data: "{{items}}"
|
||
|
||
# 图片
|
||
- type: image
|
||
src: "{{logoUrl}}"
|
||
align: center
|
||
maxWidth: 200
|
||
|
||
# 条码
|
||
- type: barcode
|
||
format: "CODE128" # CODE128 | QR | EAN13
|
||
data: "{{orderId}}"
|
||
align: center
|
||
height: 64
|
||
|
||
# 空行
|
||
- type: space
|
||
lines: 2
|
||
```
|
||
|
||
### 2.2 支持的块类型
|
||
|
||
| 类型 | 用途 | 关键属性 |
|
||
|------|------|---------|
|
||
| `text` | 普通文本 | `content`, `align`, `fontSize`, `bold`, `italic`, `underline`, `lineHeight`, `marginTop`, `marginBottom` |
|
||
| `list` | 循环渲染数组 | `data`, `itemTemplate` |
|
||
| `table` | 多列表格 | `columns`, `data` |
|
||
| `row` | 多列行布局 | `columns` |
|
||
| `divider` | 分隔线 | `char` |
|
||
| `image` | 图片/Logo | `src`, `align`, `maxWidth` |
|
||
| `barcode` | 条码/二维码 | `format`, `data`, `height` |
|
||
| `space` | 空行 | `lines` |
|
||
|
||
### 2.3 样式属性
|
||
|
||
```yaml
|
||
# 对齐
|
||
align: left | center | right
|
||
|
||
# 字体大小
|
||
fontSize: small | normal | large | xlarge
|
||
|
||
# 文本样式
|
||
bold: true | false
|
||
italic: true | false # 打印机支持时
|
||
underline: true | false
|
||
|
||
# 间距
|
||
lineHeight: 1.0 # 行高倍数
|
||
marginTop: 0 # 上方间距(行数)
|
||
marginBottom: 0 # 下方间距(行数)
|
||
|
||
# 列宽(仅 row/table)
|
||
width: 50% | 20 # 百分比或字符数
|
||
```
|
||
|
||
### 2.4 数据绑定
|
||
|
||
使用 Mustache 语法 `{{variable}}`:
|
||
|
||
```yaml
|
||
content: "订单编号: {{orderId}}"
|
||
data: "{{items}}" # 列表数据源
|
||
```
|
||
|
||
支持嵌套访问:
|
||
```yaml
|
||
content: "{{customer.name}} - {{customer.phone}}"
|
||
```
|
||
|
||
### 2.5 Schema 自动生成
|
||
|
||
系统从模板的 `{{变量}}` 自动提取数据结构:
|
||
|
||
```yaml
|
||
# 模板示例
|
||
blocks:
|
||
- content: "{{orderType}} - {{orderId}}"
|
||
- data: "{{items}}"
|
||
```
|
||
|
||
自动生成:
|
||
```json
|
||
{
|
||
"type": "object",
|
||
"properties": {
|
||
"orderType": { "type": "string" },
|
||
"orderId": { "type": "string" },
|
||
"items": { "type": "array" }
|
||
}
|
||
}
|
||
```
|
||
|
||
通过 `GET /api/templates/:id/schema` 获取 Schema 和示例数据。
|
||
|
||
## 3. Web 配置页
|
||
|
||
### 3.1 核心功能
|
||
|
||
1. **模板编辑器**
|
||
- 左侧:YAML 代码编辑(语法高亮 + 错误提示)
|
||
- 右侧:实时预览(HTML 模拟小票效果)
|
||
|
||
2. **块类型选择器**
|
||
- 快捷插入按钮(文本、表格、图片、分隔线等)
|
||
- 点击后插入模板代码片段
|
||
|
||
3. **数据模拟器**
|
||
- 基于 Schema 生成表单
|
||
- 输入模拟数据测试渲染
|
||
- 保存测试数据集
|
||
|
||
4. **打印机设置**
|
||
- IP 地址配置
|
||
- 打印测试页
|
||
- 打印队列状态
|
||
|
||
### 3.2 界面布局
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ [Logo] 小票打印机 [打印机状态 ●] │
|
||
├────────────┬────────────────────────┬───────────────────┤
|
||
│ │ │ │
|
||
│ 模板列表 │ YAML 编辑器 │ 实时预览 │
|
||
│ ─────── │ │ │
|
||
│ daily-todo│ │ ┌─────────┐ │
|
||
│ food-order│ - type: text │ │ 📋 待办 │ │
|
||
│ ticket │ content: "..." │ │ ======= │ │
|
||
│ │ │ │ [☐] ... │ │
|
||
│ [+ 新建] │ │ └─────────┘ │
|
||
│ │ │ │
|
||
├────────────┴────────────────────────┴───────────────────┤
|
||
│ 块类型: [文本] [表格] [图片] [分隔线] [条码] [空行] │
|
||
└─────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## 4. 设计参考
|
||
|
||
### 4.1 餐饮小票(麦当劳风格)
|
||
|
||
```yaml
|
||
blocks:
|
||
# 顶部双栏
|
||
- type: row
|
||
columns:
|
||
- content: "外带"
|
||
align: left
|
||
- content: "订单编号: {{orderId}}"
|
||
align: right
|
||
- type: divider
|
||
char: "-"
|
||
|
||
# 商品列表(带缩进备注)
|
||
- type: list
|
||
data: "{{items}}"
|
||
itemTemplate:
|
||
- type: text
|
||
content: "{{quantity}} {{name}}"
|
||
- type: list
|
||
data: "{{notes}}"
|
||
itemTemplate:
|
||
- type: text
|
||
content: " {{.}}"
|
||
fontSize: small
|
||
- type: divider
|
||
char: "-"
|
||
|
||
# 取餐号(超大)
|
||
- type: text
|
||
content: "取餐柜取餐"
|
||
align: center
|
||
marginBottom: 0
|
||
- type: text
|
||
content: "{{pickupNumber}}"
|
||
align: center
|
||
fontSize: xlarge
|
||
bold: true
|
||
marginBottom: 1
|
||
|
||
# 条码
|
||
- type: barcode
|
||
format: "CODE128"
|
||
data: "{{pickupNumber}}"
|
||
align: center
|
||
|
||
# 时间戳
|
||
- type: row
|
||
columns:
|
||
- content: "MOBILE"
|
||
align: left
|
||
fontSize: small
|
||
- content: "{{timestamp}}"
|
||
align: right
|
||
fontSize: small
|
||
```
|
||
|
||
### 4.2 精致小票(铁板烧风格)
|
||
|
||
```yaml
|
||
blocks:
|
||
# Logo 图片
|
||
- type: image
|
||
src: "{{logoUrl}}"
|
||
align: center
|
||
maxWidth: 150
|
||
marginBottom: 0
|
||
|
||
# 英文小字
|
||
- type: text
|
||
content: "THE SOURCE OF THIS DESIGN MATERIAL IS TEPPANYAKI DESIGN"
|
||
align: center
|
||
fontSize: small
|
||
|
||
# 中文标题
|
||
- type: text
|
||
content: "铁板烧设计"
|
||
align: center
|
||
bold: true
|
||
marginBottom: 1
|
||
|
||
# 装饰分隔线
|
||
- type: divider
|
||
char: "="
|
||
marginBottom: 1
|
||
|
||
# 表头
|
||
- type: row
|
||
columns:
|
||
- content: "商品名称"
|
||
align: left
|
||
bold: true
|
||
width: 50%
|
||
- content: "数量"
|
||
align: center
|
||
bold: true
|
||
width: 25%
|
||
- content: "金额"
|
||
align: right
|
||
bold: true
|
||
width: 25%
|
||
|
||
# 表格数据
|
||
- type: table
|
||
columns:
|
||
- align: left
|
||
width: 50%
|
||
- align: center
|
||
width: 25%
|
||
- align: right
|
||
width: 25%
|
||
data: "{{items}}"
|
||
|
||
# 汇总
|
||
- type: divider
|
||
char: "="
|
||
- type: row
|
||
columns:
|
||
- content: "小计"
|
||
align: left
|
||
- content: "¥{{subtotal}}"
|
||
align: right
|
||
```
|
||
|
||
## 5. 技术决策
|
||
|
||
### 5.1 为什么选择 YAML?
|
||
|
||
- 比 JSON 更易手写(支持注释、多行字符串)
|
||
- 比纯代码更声明式(专注"是什么"而非"怎么做")
|
||
- 主流编辑器支持语法高亮和验证
|
||
|
||
### 5.2 为什么自动生成 Schema?
|
||
|
||
- 降低用户负担(无需学习 JSON Schema)
|
||
- 保持数据和模板同步(一处修改,处处生效)
|
||
- 自动生成文档和表单
|
||
|
||
### 5.3 为什么用 HTML 预览?
|
||
|
||
- 无需连接真实打印机即可调试
|
||
- 跨平台、易实现
|
||
- 样式可精确还原(CSS)
|
||
|
||
## 6. 待决策事项
|
||
|
||
- [ ] 是否支持模板继承/复用?
|
||
- [ ] 是否支持条件渲染(if/else)?
|
||
- [ ] 是否支持自定义字体?
|
||
- [ ] 是否支持打印历史记录?
|
||
- [ ] 是否支持多打印机管理?
|