帮助文档
{{userInfo.nickname}}
用户设置 退出登录

{{wikiTitle}}

小票打印

一、功能概述

本模块实现基于易联云API的订单小票打印功能,支持手动触发打印与支付成功自动打印两种模式,包含完整的权限校验、打印状态检测、订单数据组装、第三方服务调用能力。

二、核心流程

start
:触发打印请求;
if (权限校验通过?) then (是)
  else (否)
  :返回403无权限;
  stop
endif
if (打印总开关开启?) then (是)
  else (否)
  :抛出"未开启打印"异常;
  stop
endif
if (自动打印模式?) then (是)
  if (自动打印配置开启?) then (是)
  else (否)
    :跳过打印;
    stop
  endif
endif
:校验订单状态;
if (订单存在且已支付?) then (是)
  else (否)
  :抛出订单异常;
  stop
endif
:构造打印数据;
:调用易联云API;
if (调用成功?) then (是)
  :记录成功日志;
  else (否)
  :记录错误日志;
endif
stop

三、核心代码结构详解

1.判断打印模式

public void YlyPrint(String orderId,boolean isAuto) {...}

isAuto 是否自动打印参数,手动触发传入false,支付成功传入true。

2.打印数据构造器

List<YlyPrintRequestGoods> goods = orderItems.stream()
    .map(item -> new YlyPrintRequestGoods(...)).collect(...);

3.第三方服务调用

ylyUtil.ylyPrint(ylyPrintRequest); // 实际调用易联云SDK

4.YlyUtil工具类核心说明

YlyUtil作为易联云打印服务核心工具类,承担以下职责:
打印机初始化及Token管理
打印指令生成与协议封装
语音/音量等设备控制
打印状态配置读取

1.核心方法说明
// 初始化打印机连接
public void instant() {
    // 从配置中心加载参数
    client_id = systemConfigService.getValueByKey(YlyConstants.YLY_PRINT_APP_ID);
    ...
    // 获取/刷新AccessToken
    if (redisUtil.exists(YlyConstants.YLY_REDIS_TOKEN)) {
        // 从Redis读取缓存Token
    } else {
        // 调用易联云API获取新Token
    }
    // 添加打印机设备
    RequestMethod.getInstance().addPrinter(...);
}

// 执行小票打印
public void ylyPrint(YlyPrintRequest request) throws Exception {
    // 构建打印内容模板
    String printSb = "<FH><FB><center>...</center></FB></FH>";
    // URL编码后发送打印指令
    RequestMethod.getInstance().printIndex(..., URLEncoder.encode(printSb, "utf-8"), ...);
}

// 校验自动打印配置
public boolean checkYlyPrintAfterPaySuccess() {
    return "1".equals(systemConfigService.getValueByKey(YlyConstants.YLY_PRINT_AUTO_STATUS));
}
2.打印模板定制策略

模板结构分析

    <!-- 模板示例 -->
    <FH><FB><center>{商户名称}</center></FB></FH>
    ********************************
    <FH>
    订单编号:{订单号}
    日期:{支付时间}
    ...
    </FH>
    ********************************
    <FH>
    商品名称 单价 数量 金额
    {商品列表}
    </FH>
    ********************************
    <FH>
    <LR>合计:¥{总金额}元,优惠:¥{优惠金额}元</LR>
    ...
    </FH>

定制修改步骤
1.修改模板内容

    调整ylyPrint()方法中的HTML模板字符串,支持以下控制指令:
    <!-- 排版指令 -->
    <FB>   <!-- 加粗 -->
    <FH>   <!-- 恢复默认 -->
    <center>  <!-- 居中 -->
    <LR>左列:右列</LR>  <!-- 分列显示 -->

2.增加自定义字段

// 在YlyPrintRequest中新增字段
private String memberLevel;

// 模板中插入新字段
printSb.append("会员等级:" + request.getMemberLevel() + "\n");

3.使用模板引擎(推荐)
引入Freemarker模板引擎:

Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
cfg.setClassForTemplateLoading(this.getClass(), "/templates");
Template temp = cfg.getTemplate("yly.ftl");
String html = FreeMarkerTemplateUtils.processTemplateIntoString(temp, dataModel);

四、二开策略指南

1. 更换打印服务商(如飞鹅云)

实施步骤:

1.实现新服务商接口:
public interface PrinterAdapter {
    void initPrinter() throws PrinterException;
    void printReceipt(ReceiptData data) throws PrinterException;
}

@Component("feiyunAdapter")
public class FeiyunAdapter implements PrinterAdapter {
    // 实现飞鹅云SDK调用
}
2.修改服务层调用点:
@Autowired @Qualifier("feiyunAdapter")
private PrinterAdapter printerAdapter;

public void YlyPrint(...) {
    printerAdapter.printReceipt(convertData(ylyPrintRequest));
}

2. 增加打印队列

优化方案:


// 在YlyPrintServiceImpl中注入RabbitTemplate
@Autowired
private RabbitTemplate rabbitTemplate;

// 修改打印方法
@Async
public void YlyPrint(String orderId, boolean isAuto) {
    // 验证逻辑...
    rabbitTemplate.convertAndSend("print.task.queue", printRequest);
}

// 定义队列消费者
@RabbitListener(queues = "print.task.queue")
public void handlePrintTask(PrintRequest request) {
    try {
        ylyUtil.ylyPrint(request);
    } catch (Exception e) {
        redisUtil.lPush("print:retry:queue", request);
    }
}

3. 扩展打印内容

场景示例:增加会员积分显示
扩展数据对象:

public class YlyPrintRequest {
    // 新增字段
    private Integer usePoints;
    private String pointsRule;
}

修改模板构造:

printSb.append("<FH>使用积分:" + request.getUsePoints() + "(" + request.getPointsRule() + ")</FH>\n");

在订单处理层填充数据:

ylyPrintRequest.setUsePoints(order.getUseIntegral());
ylyPrintRequest.setPointsRule("100积分抵1元");

五、注意事项

编码规范:

打印内容必须使用URLEncoder.encode(printSb, “utf-8”)进行编码
AccessToken缓存时间需小于易联云有效期(35天)

{{cateWiki.like_num}}人点赞
0人点赞
评论({{cateWiki.comment_num}}) {{commentWhere.order ? '评论从旧到新':'评论从新到旧'}} {{cateWiki.page_view_num}}人看过该文档
评论(0) {{commentWhere.order ? '评论从旧到新':'评论从新到旧'}} 278人看过该文档
评论
{{item.user ? item.user.nickname : ''}} (自评)
{{item.content}}
{{item.create_time}} 删除
{{item.like ? item.like.like_num : 0}} {{replyIndex == index ? '取消回复' : '回复'}}
评论
{{items.user ? items.user.nickname : '暂无昵称'}} (自评)
{{items.content}}
{{items.create_time}} 删除
{{items.like ? items.like.like_num : 0}} {{replyIndexJ == (index+'|'+indexJ) ? '取消回复' : '回复'}}
评论
目录
  • {{item}}