# 语法
模板采用 freemarker 引擎解析,所以原生支持所有的 freemarker 语法,你可以自行百度一下 freemarker 语法的简单使用,包括如何判断、如何循环、如何格式化处理数据等等
# 标签支持
## 小票打印机
打印机使用标签(类似 html 格式)来格式化输出内容,具体说明如下:
```plain
:换行符
:切刀指令(主动切纸,仅限切刀打印机使用才有效果)
:打印LOGO指令(前提是预先在机器内置LOGO图片)
:钱箱或者外置音响指令
:居中放大
:放大一倍
:居中
:字体变高一倍
:字体变宽一倍
:二维码(单个订单,最多只能打印一个二维码)
:右对齐
:字体加粗
说明:来订单时默认播放新来单语音,若使用“申请退单”或“申请取消订单”的语音,请使用以下指令
:申请退单语音指令。播报内容为:有用户申请退单了
:申请取消订单语音指令。播报内容为:有用户申请取消订单了
条形码标签仅支持以下标签规定的内容打印
123ABCDEF :数字和大写字母混合的条形码,最多支持14位的数字、大写字母混合条形码
123ABCDef :数字和大小写字母混合的条形码,最多支持14位的数字、大写字母、小写字母混合条形码
0123456789 :最多支持22位纯数字
```
### 参考模板A
```plain
${order.id} 号
${.now?datetime}
名称 数量 金额
--------------------------------
<#list goods as test>
${test.goodsName} ${test.property!""} ${test.number} ${test.amount}
#list>
--------------------------------
合计:${order.amountReal}元
订单号:${order.orderNumber}
联系电话:0571-28180512
https://www.it120.cc/
```
### 参考模版B
```json
小程序订单
${order.id}
${.now?datetime}
<#list goods as test>
${test.goodsName} ${test.property!""}
数量:${test.number} 金额:${test.amount}
--------------------------------
#list>
优惠券抵扣:${order.amountCoupons}
备注:${order.remark!"无"}
--------------------------------
姓名:${extJson["姓名"]}
电话:${extJson["手机号码"]}
用餐时段:${extJson["用餐时间段"]}
用餐日期:${extJson["自取时间"]}
--------------------------------
<#if order.isNeedLogistics>
联系人: ${logistics.linkMan}
联系电话: ${logistics.mobile}
配送地址:${logistics.address}
#if>
<#if order.isCanHx>
${order.hxNumber}
自取点: ${extJson["提货点"]}
<#else>
${order.pickPointPwd}
取餐柜: ${extJson["提货点"]}
取餐码: ${order.pickPointPwd}
#if>
合计:${order.amountReal}元
订单号:${order.orderNumber}
```
### 参考模版C
```javascript
<#if order.isNeedLogistics>外卖订单<#else>门店订单#if>
${order.qudanhao}
${order.orderNumber}
武汉国际广场店
027-xxxxxxxxxxxx
「新茶飲开创者」
2012年,在奶精、奶蓄粉、果粉盛行的年代,我们在江门江边里的一条小巷里创道出第一杯芝士茶,并使用真牛乳、新鲜水果、真茶、賈糖等天然原料,开创了大家所熟知的“新菜饮时代”。同时,我们也养望成为一扇灵感窗口,推动新茶饮进入岂止于茶的设计世界。
扫码查看取餐进度
https://wxaurl.cn/80kzL5wVumm
--------------------------------
${stringMaxWidth("商品名称", 20)}${stringMaxWidth("数量", 6)}${stringMaxWidth("金额", 6)}
--------------------------------
<#list goods as test>
${stringMaxWidth(test.goodsName, 20)}${stringMaxWidth(test.number, 6)}${stringMaxWidth(test.amount, 6)}
#list>
--------------------------------
${stringMaxWidth("合计", 26)}${stringMaxWidth(order.amount, 6)}
--------------------------------
${stringMaxWidth("应付金額", 26)}${stringMaxWidth(order.amountReal, 6)}
<#if order.isNeedLogistics>
「配送地址」
联系人: ${logistics.linkMan}
电话: ${logistics.mobile}
地址:${logistics.address}
#if>
「真品质 不昂贵」
奉上日常好茶
「喜一下 灵感来了」
做人要开心
```
## 标签机
```plain
n :
设定打印时出纸和打印字体的方向,n 0 或 1,每次设备重启后都会初始化为 0 值设置,1:正向出纸,0:反向出纸,
如1
二维码内容:
打印二维码,其中属性x为水平方向起始点坐标(默认为0),属性y为垂直方向起始点坐标(默认为0),属性e为纠错等级:
L 7%M 15%Q 25%H 30%(默认为K),属性w为二维码宽度(默认为5)
文本内容:
打印文本,其中属性x为水平方向起始点坐标(默认为0),属性y为垂直方向起始点坐标(默认为0),属性font为字体:
1、 8×12 dot 英数字体
2、 12×20 dot 英数字体
3、 16×24 dot 英数字体
4、 24×32 dot 英数字体
5、 32×48 dot 英数字体
6、 14×19 dot 英数字体 OCR-B
7、 21×27 dot 英数字体 OCR-B
8、 14×25 dot 英数字体 OCR-A
9、 9×17 dot 英数字体
10、 12×24 dot 英数字体
11、 繁体中文 24×24Font(大五码)
12、 简体中文 24×24Font(GB 码)
13、 韩文 24×24Font(KS 码)
默认为12 简体中文 24×24Font(GB 码),属性w为文字宽度放大倍率1-10(默认为1),属性h为文字高度放大倍率1-10
属性r为文字旋转角度(顺时针方向):
0 0度
90 90度
180 180度
270 270度
(默认为0)
12345678:打印code128一维码,其中属性x为水平
方向起始点坐标(默认为0),属性y为垂直方向起始点坐标(默认为0),属性s是否人眼可识:0 不可识,1 可识(默认为1),
属性n为窄 bar 宽度,以点(dot)表示(默认为1),属性w为宽 bar 宽度(默认为1),以点(dot)表示,属性r为文字旋转角度
(顺时针方向):
0 0度
90 90度
180 180度
270 270度
(默认为0)
12345678:打印code39一维码,其中属性x为水平方向
起始点坐标(默认为0),属性y为垂直方向起始点坐标(默认为0),属性s是否人眼可识:0 不可识,1 可识(默认为1),属性
n为窄bar宽度,以点(dot)表示(默认为1),属性w为宽 bar 宽度(默认为2),以点(dot)表示,属性r为文字旋转角度(顺时针
方向):
0 0度
90 90度
180 180度
270 270度
(默认为0)
```
上述标签中的数字单位是 dot ,按照 1mm = 8dots,自行根据自己的标签尺寸进行设置
### 参考模版
```plain
1
#001 五号桌 1/3
可乐鸡翅
张三先生 13800138000
```
# 可用变量
## 打印时间
```plain
${.now?string('yyyy-MM-dd HH:mm:ss')}
```
时间格式化参数说明:
1. yyyy 为4位数的年份
2. MM 为2位数的月份
3. dd 为日期
4. HH 为24小时制的小时数
5. mm 为分钟数
6. ss 为秒数
比如我要显示中文形式的时间:
```javascript
${.now?string('yyyy年MM月dd日HH点mm分ss秒')}
```
_具体可以查阅 freemarker 的使用手册_
## 订单相关变量引用
```json
${order.XXXXX}
```
后台订单详情接口返回的json数据中的 _order_ 对象里的值都可以调用,比如:
_${order.qudanhao}_ 将会打印出取餐号;
_${order.orderNumber}_ 将会打印出订单号;
_${order.amountReal}_ 将会打印出订单实际支付金额;
```json
{
"type": 1, // 2 为扫码点餐订单,1 为普通订单
"type2": "下单时候传的 extType",
"amount": 500, // 商品货款金额,不包含运费
"amountLogistics": 0, // 运费价格
"amountReal": 500, // 订单实际金额
"dateAdd": "2020-02-25 11:43:40", // 下单时间
"goodsNumber": 1, // 商品数量
"id": 464320, // 订单ID
"qudanhao": "0006", // 取餐号
"orderNumber": "20022511439510006", // 订单号
"isNeedLogistics": true, // 是否需要快递
"peisongType": 0, // 0 商家配送插件; 1 达达配送; 2 美团配送 3 闪送
"isPay": true, // 是否已支付
"pingtuanOpenId": false, // 拼团团号
"isSuccessPingtuan": false, // 是否已成团
"payNumber": "ZF2002251642338367", // 在线支付订单号
"payGate": "WXAPP", // 在线支付的支付公司编号
"payOnlineAmount": 138.00, // 在线支付金额
"remark": "不要麻也不要辣", // 备注
"tableCode": "A11", // 餐桌号
"pickPointId": "657340", // 取餐码
"shopId": 1234, // 订单归属门店ID
"shopName": "订单归属门店名称",
"shopIdZt": 1234, // 订单自提门店ID
"shopNameZt": "订单自提门店名称",
"score": "订单需要扣除多少积分",
"scoreDeduction": "该订单参与积分抵扣金额的积分数量",
"isScoreOrder": "是否积分订单",
"gotScore": "可获得多少积分",
}
```
## 订单的商品明细
```plain
<#list goods as test>
... (这里面就可以调用 ${test.XXXX} 来显示商品数据)
#list>
```
上面代码遍历打印所有的订单商品,后台订单详情接口返回的json数据中的 _goodsList_ 对象里的值都可以调用
```json
{
"amount": 500, // 商品总价
"amountSingle": 500, // 单价
"goodsId": 1234, // 商品ID
"goodsName": "WIFI 58mm 热敏打印机工厂定制版", // 商品名称
"goodsSubName": "副标题", // 商品副标题
"number": 1, // 商品数量
"unit": "盒", // 商品单位
"property": "sku信息", // 商品的规格尺寸数据
"barCode": "1212343", // 商品条码
"skuCode": "1212343", // sku规格编号
"pic": "https://cdn.it120.cc/apifactory/2019/03/07/133eb6294e3853ebe4eb8551359a26dc.png", // 商品图片
}
```
### 打印商品的详细规格尺寸
```javascript
<#list goods as test>
<#list goodsProperty(test) as pro>
${pro.property.name} -> ${pro.child.name}
#list>
#list>
```
一个订单里面可能有多个商品,所以需要循环遍历 goods
每个商品里面,也可能会包含多个规格尺寸信息,例如(颜色:红色, 尺码:XL),所以也需要遍历
`goodsProperty(test)`就是获取的这个商品的所有规格尺寸的列表数据
里面包含2个信息:
+ property 规格尺寸的分组信息,例如上例的 颜色 和 尺码
- name 名称
- remark 备注
+ child 对应规格分组下的属性信息,例如上例的 红色 和 XL
- name 名称
- remark 备注
## 收货地址
```plain
${logistics.XXXXXX}
```
后台订单详情接口返回的json数据中的 _apiExtOrderLogistics_ 对象里的值都可以调用
```json
{
"address": "详细地址",
"areaStr": "南岸区",
"cityId": "500100000000",
"cityStr": "市辖区",
"code": "322000", // 邮编
"districtId": "500108000000",
"linkMan": "收件人姓名",
"linkManMask": "收***名",
"mobile": "手机号码",
"mobileMask": "135*****890",
"provinceId": "500000000000", // 省份编号
"provinceStr": "重庆市",
"shipperName": "其他快递公司",
"trackingNumber": "快递单号",
"type": 0 // 0 快递,1 达达配送, 2 美团配送, 3 快跑者
}
```
## 所属门店数据
```plain
${shopInfo.XXXXXX}
```
如果当前订单有归属门店,那么你就可以调用上面的变量直接打印门店数据;
后台门店详情接口返回的json数据中变量都可以调用
## 门店区域数据
```plain
${shopArea.XXXXXX}
```
门店所属区域的信息:
+ name 名称
+ address 地址
## 订单扩展属性

```javascript
${extJson.XXXXXX}
或者
${extJson['XXXXXX']}
```
后台订单详情接口返回的json数据中的 _extJson_ 对象里的值都可以调用
比如要打印上图中的联系电话: `${extJson['联系电话']}`
比如要打印上图中的提货点: `${extJson['提货点']}`
## 打印下单用户信息
```json
${user.xxx}
```
其中 xxx 可以用下面的字段代替:
+ username 用户名
+ email 邮箱
+ mobile 手机
+ id 用户编号
+ nick 昵称
+ avatarUrl 头像图片路径
+ referrer 邀请人
+ gender 性别
+ birthday 生日,日期类型,所以需要 ${user.birthday?string('yyyy-MM-dd')} 格式化
+ levelId 用户等级ID
## 用户资产情况
```javascript
${userCash.xxx}
```
其中 xxx 可以用下面的字段代替:
+ balance 可用余额
+ freeze 冻结余额
+ score 剩余可用积分
+ totleConsumed 累计消费金额
+ growth 成长值
+ totalWithdraw 累计提现金额
+ totalPayNumber 累计支付笔数
+ totalScore 累计获得积分数
+ totalPayAmount 累计支付金额
+ fxCommisionPaying 待结算分销佣金
## 标签机商品拆分打印变量
```xml
${goodsIndex}
```
当前打印第几种商品(从 0 开始)
```xml
${goodsNumberIndex}
```
当前打印的某种商品的第几个(最大为用户购买的总数)
```xml
${gIdx}
```
假如用户下单3种商品,每种商品各2个,那么如果是数量拆开打印的话,这个变量将依次打印 1-6;如果数量合并打印的话,这个变量将依次打印 1-3;如果是汇总打印的话,这个变量固定为 1
```plain
${curGoods.XXXXXX}
```
```json
{
"amount": 500, // 商品总价
"amountSingle": 500, // 单价
"goodsName": "WIFI 58mm 热敏打印机工厂定制版", // 商品名称
"number": 1, // 商品数量
"pic": "https://cdn.it120.cc/apifactory/2019/03/07/133eb6294e3853ebe4eb8551359a26dc.png", // 商品图片
}
```
## 打印套餐内商品明细
```plain
${goodsPackageContent(1514858, '2023-08-24')}
```
+ 第一个参数为商品ID
+ 第二个参数为日期,打印这个日期的套餐内配菜情况
## 订单的优惠券明细信息
```plain
<#if coupons??>
<#list coupons as test>
... (这里面就可以调用 ${test.XXXX} 来显示优惠券数据)
#list>
#if>
```
+ type 优惠券类型
+ name 优惠券名字
+ money 优惠券金额
+ moneyType 0 固定金额 1比例
+ remark 备注
+ source 优惠券来源
# 固定显示文字数量
## 使用 stringMaxWidth
```javascript
${stringMaxWidth(原始字符串, 字符数)}
```
比如:
```javascript
${stringMaxWidth("aaaaaaaaaaaaa", 5)} // 输出5个a
${stringMaxWidth("a", 5)} // 输出1个a以及4个空格
```
## Freemarker 原生实现
比如标签机,文字不会自动换行,所以需要可以变量的文字长度,自动进行换行,那么,就需要可以截取显示字数长度进行控制:
比如下面的这句代码,本来是打印商品的规格信息,但是如果规格太长,标签机又不会自动换行,就会无法打印剩下的文字内容:
```html
${curGoods.property}
```
假如一行只能打印 10 个字(只是举例),那么上面的这句语句就可以改成:
```bash
<#if curGoods.property?? && curGoods.property?length gt 10>
${curGoods.property?substring(0,10)}
${curGoods.property?substring(10)}
<#else>
${curGoods.property}
#if>
```