Initial commit: Receipt Printer design docs and examples

This commit is contained in:
Developer 2026-02-12 07:14:10 +00:00
commit 1c4187cb29
10 changed files with 1554 additions and 0 deletions

125
PROJECT.md Normal file
View File

@ -0,0 +1,125 @@
# Receipt Printer 项目
## 项目概述
一个基于 WiFi ESC/POS 协议的 80mm 小票打印系统,支持:
- 可视化模板配置YAML + 实时预览)
- REST API 调用打印
- 自动从模板提取数据 Schema
- 多种排版元素(文本、表格、图片、条码等)
## 技术栈
- **Runtime**: Bun
- **Web 框架**: Hono
- **模板引擎**: Mustache
- **配置格式**: YAML
## 项目结构
```
receipt-printer/
├── README.md # 项目说明
├── package.json # 依赖配置
├── docs/
│ ├── design.md # 系统设计文档
│ └── api.md # API 规范
├── templates/examples/ # 示例模板
│ ├── daily-todo.yaml # 每日待办
│ ├── food-order-simple.yaml # 餐饮订单
│ ├── fancy-receipt.yaml # 精致账单
│ ├── ticket-list.yaml # Ticket 列表
│ └── long-text.yaml # 长文阅读
└── src/ # 源码目录(待开发)
```
## 核心设计决策
### 1. 模板配置格式
使用 YAML 而非 JSON
- 支持注释
- 多行字符串更友好
- 编辑器支持语法高亮
### 2. Schema 自动生成
- 从模板中的 `{{变量}}` 自动提取
- 无需手动维护数据结构
- API 可 introspect 获取数据要求
### 3. 块类型系统
| 类型 | 用途 |
|------|------|
| text | 普通文本(支持样式) |
| row | 多列行布局 |
| table | 多列表格 |
| list | 循环渲染数组 |
| divider | 分隔线 |
| image | 图片 |
| barcode | 条码/二维码 |
| space | 空行 |
### 4. 样式支持
- 对齐left/center/right
- 字体大小small/normal/large/xlarge
- 文本样式bold/italic/underline
- 间距lineHeight/marginTop/marginBottom
## API 设计概览
```
POST /api/print/:templateId # 打印
GET /api/templates # 列出模板
GET /api/templates/:id # 获取模板
POST /api/templates # 创建模板
PUT /api/templates/:id # 更新模板
DELETE /api/templates/:id # 删除模板
GET /api/templates/:id/schema # 获取数据 Schema
GET /api/jobs/:id # 查询任务状态
GET /api/printer/status # 打印机状态
POST /api/printer/test # 打印测试页
```
## 下一步开发计划
1. **核心引擎**
- YAML 模板解析
- Mustache 数据绑定
- ESC/POS 指令生成
2. **打印驱动**
- WiFi 打印机连接
- 指令发送队列
- 状态轮询
3. **Web 服务**
- Hono HTTP 服务
- REST API 实现
- 静态文件服务
4. **配置界面**
- YAML 编辑器CodeMirror
- 实时预览HTML 模拟)
- 数据模拟器
5. **示例与文档**
- 更多模板示例
- API 使用示例
- 部署指南
## 示例模板使用
```bash
# 打印每日待办
curl -X POST http://localhost:3000/api/print/daily-todo \
-H "Content-Type: application/json" \
-d '{
"data": {
"date": "2025-02-12",
"tasks": [
{"status": "☐", "title": "修复 Bug #123"},
{"status": "☑", "title": "代码审查"}
],
"completedCount": 1
}
}'
# 获取模板 Schema
curl http://localhost:3000/api/print/daily-todo/schema
```

67
README.md Normal file
View File

@ -0,0 +1,67 @@
# Receipt Printer - 80mm 小票打印系统
基于 WiFi ESC/POS 的 80mm 小票打印系统,支持可视化模板配置和 REST API 调用。
## 核心特性
- 🎨 **可视化模板配置** - Web 界面实时编辑和预览
- 📝 **YAML/JSON 模板** - 声明式排版配置
- 🔌 **REST API** - 通过 HTTP 调用打印
- 📐 **自动 Schema 提取** - 从模板变量自动生成数据契约
- 🖨️ **WiFi ESC/POS** - 支持主流 80mm 热敏打印机
## 技术栈
- **后端**: Bun + Hono (轻量高性能)
- **模板引擎**: 自研 YAML → ESC/POS 转换器
- **前端**: 原生 HTML/JS (轻量化)
- **打印机协议**: ESC/POS over TCP
## 项目结构
```
├── docs/ # 设计文档
├── templates/ # 模板文件
├── src/ # 源码
│ ├── server.ts # HTTP 服务
│ ├── printer.ts # 打印机驱动
│ ├── template.ts # 模板引擎
│ └── static/ # Web 界面
└── README.md
```
## 快速开始
```bash
# 安装依赖
bun install
# 配置打印机
bun run config
# 启动服务
bun run start
# 打开配置页面
open http://localhost:3000
```
## API 示例
```bash
# 打印模板
curl -X POST http://localhost:3000/api/print/daily-todo \
-H "Content-Type: application/json" \
-d '{
"data": {
"date": "2025-02-12",
"tasks": [
{"status": "☐", "title": "修复 Bug #123"}
]
}
}'
```
## 许可证
MIT

425
docs/api.md Normal file
View File

@ -0,0 +1,425 @@
# API 规范
## 基础信息
```
Base URL: http://localhost:3000/api
Content-Type: application/json
```
## 端点列表
### 1. 打印
#### 执行打印
```
POST /print/:templateId
```
**请求体:**
```json
{
"data": {
"date": "2025-02-12",
"tasks": [
{"status": "☐", "title": "修复 Bug #123"},
{"status": "☑", "title": "代码审查"}
]
},
"options": {
"copies": 1,
"cutPaper": true
}
}
```
**参数说明:**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `data` | object | 是 | 模板数据,结构由模板 Schema 定义 |
| `options.copies` | number | 否 | 打印份数,默认 1 |
| `options.cutPaper` | boolean | 否 | 是否切纸,默认 true |
**成功响应 (200)**
```json
{
"success": true,
"jobId": "job_abc123",
"status": "queued",
"estimatedTime": "5s"
}
```
**错误响应 (400/404/500)**
```json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "数据验证失败",
"details": [
"tasks: 必填字段缺失"
]
}
}
```
**错误码说明:**
| 错误码 | HTTP 状态 | 说明 |
|--------|-----------|------|
| `TEMPLATE_NOT_FOUND` | 404 | 模板不存在 |
| `VALIDATION_ERROR` | 400 | 数据验证失败 |
| `PRINTER_OFFLINE` | 503 | 打印机离线 |
| `TEMPLATE_RENDER_ERROR` | 500 | 模板渲染失败 |
| `PRINT_FAILED` | 500 | 打印失败 |
---
### 2. 模板管理
#### 列出所有模板
```
GET /templates
```
**响应:**
```json
{
"success": true,
"templates": [
{
"id": "daily-todo",
"name": "每日待办",
"description": "打印今日待办事项列表",
"updatedAt": "2025-02-12T07:00:00Z"
}
]
}
```
#### 获取单个模板
```
GET /templates/:id
```
**响应:**
```json
{
"success": true,
"template": {
"id": "daily-todo",
"name": "每日待办",
"config": { /* 完整模板配置 */ }
}
}
```
#### 创建模板
```
POST /templates
```
**请求体:**
```json
{
"id": "food-order",
"name": "餐饮订单",
"description": "打印餐饮订单小票",
"config": {
"name": "餐饮订单",
"width": "80mm",
"blocks": [ /* 块定义 */ ]
}
}
```
**响应:**
```json
{
"success": true,
"template": {
"id": "food-order",
"name": "餐饮订单",
"createdAt": "2025-02-12T07:00:00Z"
}
}
```
#### 更新模板
```
PUT /templates/:id
```
**请求体:**(同创建,可部分更新)
```json
{
"name": "新的名称",
"config": { /* 新配置 */ }
}
```
#### 删除模板
```
DELETE /templates/:id
```
**响应:**
```json
{
"success": true,
"message": "模板已删除"
}
```
---
### 3. 模板 Schema
#### 获取模板数据 Schema
```
GET /templates/:id/schema
```
用于获取模板所需的数据结构和示例。
**响应:**
```json
{
"success": true,
"templateId": "food-order",
"schema": {
"type": "object",
"required": ["orderId", "items"],
"properties": {
"orderType": {
"type": "string",
"description": "订单类型"
},
"orderId": {
"type": "string",
"description": "订单编号"
},
"items": {
"type": "array",
"description": "商品列表",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"quantity": { "type": "number" },
"price": { "type": "number" }
}
}
}
}
},
"example": {
"orderType": "外带",
"orderId": "35205-1",
"items": [
{ "name": "双层吉士堡", "quantity": 1, "price": 22 }
]
}
}
```
---
### 4. 打印任务
#### 查询任务状态
```
GET /jobs/:jobId
```
**响应:**
```json
{
"success": true,
"job": {
"id": "job_abc123",
"templateId": "daily-todo",
"status": "completed",
"createdAt": "2025-02-12T07:00:00Z",
"startedAt": "2025-02-12T07:00:01Z",
"completedAt": "2025-02-12T07:00:05Z"
}
}
```
**状态值:**
- `queued` - 排队中
- `printing` - 打印中
- `completed` - 完成
- `failed` - 失败
- `cancelled` - 已取消
#### 列出最近任务
```
GET /jobs?limit=10&status=completed
```
**查询参数:**
| 参数 | 类型 | 说明 |
|------|------|------|
| `limit` | number | 返回数量,默认 10 |
| `status` | string | 按状态筛选 |
| `templateId` | string | 按模板筛选 |
#### 取消任务
```
DELETE /jobs/:jobId
```
仅可取消 `queued` 状态的任务。
---
### 5. 打印机管理
#### 获取打印机状态
```
GET /printer/status
```
**响应:**
```json
{
"success": true,
"printer": {
"name": "XP-80C",
"ip": "192.168.1.100",
"port": 9100,
"status": "online",
"paperStatus": "ok",
"coverStatus": "closed",
"queueLength": 0
}
}
```
**状态值:**
- `online` - 在线
- `offline` - 离线
- `error` - 错误(查看 `errorCode`
#### 打印测试页
```
POST /printer/test
```
打印一张测试页,用于检查连接和打印质量。
**响应:**
```json
{
"success": true,
"jobId": "job_test_123"
}
```
#### 更新打印机配置
```
POST /printer/config
```
**请求体:**
```json
{
"ip": "192.168.1.100",
"port": 9100,
"width": 80
}
```
---
## 认证(可选)
如需简单保护,在配置文件中启用 API Key
```yaml
security:
enabled: true
apiKey: "your-secret-key"
```
启用后,所有请求需携带 Header
```
X-API-Key: your-secret-key
```
未提供或错误的 Key 返回:
```json
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "无效的 API Key"
}
}
```
---
## WebSocket 实时状态(可选)
如需实时推送打印状态,可连接 WebSocket
```
ws://localhost:3000/ws
```
**事件类型:**
```json
// 任务状态更新
{
"type": "jobUpdate",
"data": {
"jobId": "job_abc123",
"status": "printing"
}
}
// 打印机状态更新
{
"type": "printerUpdate",
"data": {
"status": "online",
"paperStatus": "low"
}
}
```

389
docs/design.md Normal file
View File

@ -0,0 +1,389 @@
# 系统设计文档
## 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
- [ ] 是否支持自定义字体?
- [ ] 是否支持打印历史记录?
- [ ] 是否支持多打印机管理?

30
package.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "receipt-printer",
"version": "0.1.0",
"description": "80mm 小票打印系统 - 支持可视化模板配置和 REST API",
"main": "src/server.ts",
"scripts": {
"start": "bun run src/server.ts",
"dev": "bun run --watch src/server.ts",
"build": "bun build src/server.ts --outdir dist",
"test": "bun test"
},
"dependencies": {
"hono": "^4.0.0",
"js-yaml": "^4.1.0",
"mustache": "^4.2.0"
},
"devDependencies": {
"@types/js-yaml": "^4.0.9",
"@types/mustache": "^4.2.5",
"bun-types": "latest"
},
"keywords": [
"receipt",
"printer",
"esc-pos",
"thermal-printer",
"80mm"
],
"license": "MIT"
}

View File

@ -0,0 +1,58 @@
# 每日待办模板
name: "每日待办"
id: "daily-todo"
width: 80mm
description: "打印今日待办事项列表"
defaults:
fontSize: normal
lineHeight: 1.0
marginBottom: 0
page:
marginTop: 2
marginBottom: 3
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: space
lines: 1
# 分隔线
- type: divider
char: "-"
marginBottom: 1
# 统计
- type: text
content: "共 {{tasks.length}} 项待办"
align: right
fontSize: small
- type: text
content: "已完成 {{completedCount}} / {{tasks.length}}"
align: right
fontSize: small

View File

@ -0,0 +1,190 @@
# 精致小票模板(铁板烧风格)
name: "精致账单"
id: "fancy-receipt"
width: 80mm
description: "带有 Logo 和详细商品信息的精致账单"
defaults:
fontSize: normal
lineHeight: 1.0
marginBottom: 0
page:
marginTop: 2
marginBottom: 3
blocks:
# Logo 图片
- type: image
src: "{{logoUrl}}"
align: center
maxWidth: 150
marginBottom: 0
# 英文标语
- type: text
content: "{{taglineEn}}"
align: center
fontSize: small
marginBottom: 0
# 中文店名
- type: text
content: "{{shopName}}"
align: center
fontSize: large
bold: true
marginBottom: 1
# 装饰分隔线
- type: divider
char: "="
marginBottom: 1
# 菜单标题
- type: text
content: "{{menuTitle}}"
align: center
fontSize: normal
bold: true
marginBottom: 0
# 时间
- type: text
content: "{{datetime}}"
align: center
fontSize: small
marginBottom: 1
# 表头
- type: row
marginBottom: 0
columns:
- content: "商品名称"
align: left
bold: true
width: 50%
- content: "数量"
align: center
bold: true
width: 25%
- content: "金额"
align: right
bold: true
width: 25%
# 分隔线
- type: divider
char: "="
marginBottom: 0
# 商品表格
- type: table
data: "{{items}}"
columns:
- align: left
width: 50%
- align: center
width: 25%
- align: right
width: 25%
# 分隔线
- type: divider
char: "="
marginBottom: 0
# 汇总行
- type: row
marginBottom: 0
columns:
- content: "小计"
align: left
width: 50%
- content: "{{totalQuantity}}"
align: center
width: 25%
- content: "¥{{subtotal}}"
align: right
width: 25%
- type: row
marginBottom: 0
columns:
- content: "税收({{taxRate}})"
align: left
width: 50%
- content: ""
align: center
width: 25%
- content: "¥{{tax}}"
align: right
width: 25%
- type: row
marginBottom: 0
columns:
- content: "账单总额"
align: left
bold: true
width: 50%
- content: ""
align: center
width: 25%
- content: "¥{{total}}"
align: right
bold: true
width: 25%
- type: row
marginBottom: 0
columns:
- content: "折扣"
align: left
width: 50%
- content: ""
align: center
width: 25%
- content: "{{discount}}"
align: right
width: 25%
# 分隔线
- type: divider
char: "="
marginBottom: 1
# 签名区
- type: text
content: "签名"
align: left
marginBottom: 1
# 装饰
- type: text
content: "{{signature}}"
align: center
fontSize: large
italic: true
marginBottom: 1
# 底部分隔线
- type: divider
char: "="
marginBottom: 0
# 版权信息
- type: row
marginBottom: 0
columns:
- content: "★"
align: left
width: 10%
- content: "{{copyright}}"
align: center
fontSize: small
width: 80%
- content: "★"
align: right
width: 10%

View File

@ -0,0 +1,88 @@
# 餐饮订单模板(麦当劳风格)
name: "餐饮订单"
id: "food-order-simple"
width: 80mm
description: "外带餐饮订单小票"
defaults:
fontSize: normal
lineHeight: 1.0
marginBottom: 0
page:
marginTop: 2
marginBottom: 3
blocks:
# 顶部信息
- type: row
marginBottom: 0
columns:
- content: "{{orderType}}"
align: left
fontSize: normal
- content: "订单编号: {{orderId}}"
align: right
fontSize: normal
# 分隔线
- type: divider
char: "-"
marginBottom: 1
# 商品列表(带备注)
- type: list
data: "{{items}}"
itemTemplate:
- type: text
content: "{{quantity}} {{name}}"
marginBottom: 0
- type: list
data: "{{notes}}"
itemTemplate:
- type: text
content: " 不要 {{.}}"
fontSize: small
- type: divider
char: "-"
marginBottom: 0
# 取餐信息
- type: text
content: "取餐柜取餐"
align: center
fontSize: normal
marginTop: 1
marginBottom: 0
- type: text
content: "{{pickupNumber}}"
align: center
fontSize: xlarge
bold: true
marginBottom: 1
# 条码
- type: barcode
format: "CODE128"
data: "{{pickupNumber}}"
align: center
height: 64
marginBottom: 1
# 分隔线
- type: divider
char: "-"
marginBottom: 0
# 底部信息
- type: row
marginBottom: 0
columns:
- content: "MOBILE"
align: left
fontSize: small
- content: "{{timestamp}}"
align: right
fontSize: small

View File

@ -0,0 +1,75 @@
# 长文阅读模板
name: "长文阅读"
id: "long-text"
width: 80mm
description: "打印长篇文章或阅读材料"
defaults:
fontSize: normal
lineHeight: 1.2
marginBottom: 0
page:
marginTop: 2
marginBottom: 3
blocks:
# 标题
- type: text
content: "{{title}}"
align: center
fontSize: xlarge
bold: true
marginBottom: 0
# 作者
- type: text
content: "作者: {{author}}"
align: center
fontSize: small
marginBottom: 0
# 日期
- type: text
content: "{{publishDate}}"
align: center
fontSize: small
marginBottom: 1
# 分隔线
- type: divider
char: "="
marginBottom: 1
# 正文段落
- type: list
data: "{{paragraphs}}"
itemTemplate:
- type: text
content: "{{content}}"
align: left
lineHeight: 1.3
marginBottom: 1
# 空行
- type: space
lines: 2
# 分隔线
- type: divider
char: "="
marginBottom: 1
# 阅读统计
- type: text
content: "共 {{wordCount}} 字 | {{paragraphs.length}} 段落"
align: right
fontSize: small
marginBottom: 0
- type: text
content: "打印于 {{printDate}}"
align: right
fontSize: small
marginBottom: 0

View File

@ -0,0 +1,107 @@
# Ticket/Issue 列表模板
name: "Ticket 列表"
id: "ticket-list"
width: 80mm
description: "打印 GitHub/Jira 等 Ticket 或 Issue 列表"
defaults:
fontSize: normal
lineHeight: 1.0
marginBottom: 0
page:
marginTop: 2
marginBottom: 3
blocks:
# 标题
- type: text
content: "🎫 {{project}} Tickets"
align: center
fontSize: large
bold: true
marginBottom: 0
# 副标题
- type: text
content: "{{filter}} - 共 {{tickets.length}} 条"
align: center
fontSize: small
marginBottom: 1
# 分隔线
- type: divider
char: "="
marginBottom: 1
# Ticket 列表
- type: list
data: "{{tickets}}"
itemTemplate:
# Ticket 编号和状态
- type: row
marginBottom: 0
columns:
- content: "#{{id}}"
align: left
bold: true
width: 30%
- content: "[{{status}}]"
align: center
width: 35%
- content: "{{priority}}"
align: right
width: 35%
# 标题
- type: text
content: "{{title}}"
align: left
marginBottom: 0
# 标签
- type: text
content: "标签: {{labels.join ', '}}"
align: left
fontSize: small
marginBottom: 0
# 负责人和时间
- type: row
marginBottom: 0
columns:
- content: "👤 {{assignee}}"
align: left
fontSize: small
width: 50%
- content: "📅 {{dueDate}}"
align: right
fontSize: small
width: 50%
# 分隔线
- type: divider
char: "-"
marginBottom: 1
# 底部统计
- type: divider
char: "="
marginBottom: 0
- type: text
content: "按状态统计:"
align: left
fontSize: small
bold: true
marginBottom: 0
- type: list
data: "{{statusStats}}"
itemTemplate:
- type: text
content: " {{status}}: {{count}}"
align: left
fontSize: small
marginBottom: 0