医药电子面单-对接 ERP 流程指南

目录
  1. 一、流程概览
  2. 二、美团打印组件(MTOB)使用
    1. 2.1 打印组件下载&安装
    2. 2.2 建立连接
    3. 2.3 交互协议格式说明
    4. 2.4 MTOB OpenAPI 指令
      1. 2.4.1 获取打印机列表
      2. 2.4.2 获取打印机状态
      3. 2.4.3 获取打印机配置
      4. 2.4.4 设置打印机配置
      5. 2.4.5 打印/预览【重要】
      6. 2.4.5-1 模板语法【重要】
      7. 2.4.5-2 组件汇总表
      8. 2.4.5-3 组件属性表
      9. 2.4.6 打印通知【重要】
      10. 2.4.7 获取打印任务状态
      11. 2.4.8 打印任务状态变更通知
  3. 三、开放平台对接

 

一、流程概览

 

 

二、美团打印组件(MTOB)对接

2.1 打印组件下载&安装

打印组件下载&安装说明

2.2 建立连接

连接方式:支持 SocketIO、WebSocket,默认使用 SocketIO,使用 WebSocket 连接, pathname 为 '/websocket'

默认端口:[28613、28713、28813] 一般情况使用28613,特殊情况端口被占用按顺序选取第一个可用端口

// socket.io
https://localhost:28613

// websocket
wss://localhost:28613/websocket

数据大小限制:

代码示例:
// socket.io 文档
// https://socket.io/docs/v4/client-api/
import io from 'socket.io-client';

const manager = new io.Manager('https://localhost:28613', {
  reconnection: false,
  rejectUnauthorized: false,
  query: {}
});

const socket = manager.socket('/');
manager.connect();

// 连接失败
manager.on('error', () => {
  socket.close();
  socket.removeAllListeners();
  manager.close();
});

// 连接成功
socket.on('connect', () => {});

// 断开连接
socket.on('disconnect', (reason) => {
  socket.close();
  socket.removeAllListeners();
});

// 发送事件
socket.send({
  cmd: "command",
  requestID: "unique requestID",
  version: "2.0"
  // 其它请求参数
}, (arg) => {
  console.log(arg);
}); 

2.3 交互协议格式说明:

请求协议头:
{
  "cmd": "command",
  "requestID": "unique requestID",
  "version": "2.0"
}
字段名 类型 说明
cmd string 请求的命令名称
requestID string 请求的ID,用于唯一标识,请求方自己保证
version string 协议当前版本
响应协议头:
{
  "cmd": "command",
  "requestID": "unique requestID",
  "status": "success or failed"
}
        
字段名 类型 说明
cmd string 请求的命令名称
requestID string 发送请求中的ID,原封不动返回,使客户端能对应
status 'success'/'failed' 表示命令成功或失败
错误信息:
字段名 类型 说明
msg string 如果出错,错误原因

 

2.4 MTOB OpenAPI 指令

2.4.1 获取打印机列表(getPrinters)

请求:

{
  "cmd": "getPrinters",
  "requestID": "12345678901",
  "version": "1.0",
  "forceUpdate": false
}
字段名 类型 说明
forceUpdate boolean 是否同步更新打印机列表,默认 false

响应:

{
  "cmd": "getPrinters",
  "requestID": "12345678901",
  "status": "success",
  "msg": "return nothing when success, return some tips when failed",
  "defaultPrinter": "XX打印机",
  "printers": [
    {
      "id": 1,
      "name": "打印机1",
      "driver_info": "",
      "type": "DRIVER"
    }
  ]
}

字段名

类型

说明

defaultPrinter

string

默认打印机名称

printers

Printer[]

interface Printer {
id: number;
name: string;
driver_info: string | undefined;
driverPrinterSystemStatus: number | undefined;
type: 'DRIVER' | 'USB' | 'SERIALPORT' | 'BLUETOOTH' | 'NETWORK' | 'SHARED'
}

打印机列表

id:打印机 id

name:打印机名称

driver_info:驱动信息

driverPrinterSystemStatus:驱动打印机系统状态

type:打印机类型

 

2.4.2 获取打印机状态(getPrinterStatus)

请求:

{
  "cmd": "getPrinterStatus",
  "requestID": "12345678901",
  "version": "1.0",
  "printer": "打印机XXX"
}

响应:

{
  "cmd": "getPrinterStatus",
  "requestID": "12345678901",
  "status": "success",
  "msg": "return nothing when success, return some tips when failed",
  "printer": "打印机名称",
  "printerStatus": "NORMAL"
}

字段解释:

字段名

类型

说明

printer

string

打印机名称

printerStatus

string

打印机状态

NORMAL:正常

ERROR:异常

OFFLINE:脱机

SUSPENDED:暂停

NOINFO:无法获取信息(通常由于驱动安装/更新/卸载后没有重启电脑)

OPEN_LID:开盖

SHORT_PAPER:缺纸

SHORT_PAPER_OPEN_LID:缺纸&开盖

 

2.4.3 获取打印机配置(getPrinterConfig)

请求:

{
  "cmd": "getPrinterConfig",
  "requestID": "12345678901",
  "version": "1.0",
  "printer": "GP-3150TIN"
}

响应:

{
  "cmd": "getPrinterConfig",
  "requestID": "12345678901",
  "status": "success",
  "msg": "return nothing when success, return some tips when failed",
  "printer": {
    "name": "打印机名称",
    "offsetTop": 1,
    "offsetLeft": 2,
    "landscape": false,
    "scale": false,
    "scaleFactor": 100,
    "dpi": 203,
    "density": 5
    "speed": 5,
  }
}

字段解释:

字段名

类型

说明

printer.name

string

打印机名称

printer.offsetLeft

number

水平偏移量

printer.offsetTop

number

垂直偏移量

printer.landscape

boolean

是否横向打印

printer.scale

boolean

是否缩放

printer.scaleFactor

number

缩放比例

printer.dpi

number

分辨率(仅免驱打印机)

printer.density

number

打印浓度(仅免驱打印机)

printer.speed

number

打印速度(仅免驱打印机)

printer.language

'TSPL' | 'CPCL' | 'ZPL' | 'EPL'

打印指令(仅免驱打印机)

printer.gap

number

标签纸间距(仅免驱打印机)

printer.direction

0 | 1

打印出纸方向(仅免驱打印机)

printer.transferType

'row' | 'image'

免驱打印传输方式(仅免驱打印机)

row:原始指令

image:转图片

 

2.4.4 设置打印机配置(setPrinterConfig)

请求:

{
  "cmd": "setPrinterConfig",
  "requestID": "12345678901",
  "version": "1.0",
  "printer": {
    "name": "打印机名称",
    "offsetTop": 1,
    "offsetLeft": 2,
    "landscape": false,
    "speed": 5,
    "dpi": 203,
    "density": 5
  }
}

响应:

{
  "cmd": "setPrinterConfig",
  "requestID": "12345678901",
  "status": "success",
  "msg": "return nothing when success, return some tips when failed"
}

字段解释:

字段名

类型

说明

printer.name

string

打印机名称

printer.offsetLeft

number

水平偏移量

printer.offsetTop

number

垂直偏移量

printer.landscape

boolean

是否横向打印

printer.scale

boolean

是否缩放

printer.scaleFactor

number

缩放比例

printer.dpi

number

分辨率(仅免驱打印机)

printer.density

number

打印浓度(仅免驱打印机)

printer.speed

number

打印速度(仅免驱打印机)

printer.language

'TSPL' | 'CPCL' | 'ZPL' | 'EPL'

打印指令(仅免驱打印机)

printer.gap

number

标签纸间距(仅免驱打印机)

printer.direction

0 | 1

打印出纸方向(仅免驱打印机)

printer.transferType

'row' | 'image'

免驱打印传输方式(仅免驱打印机)

row:原始指令

image:转图片

 

2.4.5 打印/预览(print)

开放平台对接完成后,调用查询电子面单模版查询电子面单打印数据接口,组装打印数据,下发打印指令

请求:

{
  "cmd": "print",
  "requestID": "{String|UUID}",
  "version": "2.0",
  "task": {
    "taskID": "{String|建议YYYYMMDD+随机数+四位自增数}",
    // 注意:projectId 必传,美团医药业务参数,否则可能会打印失败
    // 注意:projectId 必传,美团医药业务参数,否则可能会打印失败
    "projectId": "yiyao-b-b2c",
    "printer": "{String|打印机名称}",
    "documents": [
      {
        "documentID": "{String|自增ID,建议DOC+自增数}",
        "contents": [
          // 标准模板区域
          {
            "data": {
              "waybillNo": "{运单号}",
              "mark": "{大头笔}",
              "printTime": "{打印时间}",
              "bagAddress": "{集包地}",
              "receiverName": "{收件人姓名}",
              "receiverPhone": "{收件人电话}",
              "receiverAddress": "{收件人地址}",
              "senderName": "{发货人姓名}",
              "senderPhone": "{发货人电话}",
              "senderAddress": "{发货人地址}",
              "endType": "{末端类型-韵达}",
              "stationCode": "{驿站码-韵达、极兔}",
              "secondCode": "{二段码-圆通}",
              "endName": "{末端简称-韵达}",
              "waybillFourthSegmentCode": "{四段码-极兔}",
              "proCode": "{产品码-顺丰}",
              "twoDimensionCode": "{二维码-顺丰}",
              "codingMapping": "{映射码-顺丰}",
              "extend": {
                "endType": "{末端类型-韵达}",
                "stationCode": "{驿站码-韵达、极兔}",
                "secondCode": "{二段码-圆通}",
                "endName": "{末端简称-韵达}",
                "waybillFourthSegmentCode": "{四段码-极兔}",
                "proCode": "{产品码-顺丰}",
                "twoDimensionCode": "{二维码-顺丰}",
                "codingMapping": "{映射码-顺丰}"
              }
            },
            "templateURL": "{String|模版链接,从开放接口获取}"
          },
          // 自定义模板区域
          {
            "templateURL": "{自定义区域模板 URL}",
            "data": {}
          }
        ]
      }
    ],
    "customTags": {
      "printType": "WAYBILL",
      "appName": "com.sankuai.yiyaobb2cpf.merchant",
      "wmPoiId": "{String|门店ID}",
      // 注意:from 必传,美团医药业务识别来源参数,否则可能会打印失败
      // 注意:from 必传,美团医药业务识别来源参数,否则可能会打印失败
      "from": "{String|ERP名称,如:聚水潭/旺店通/XXX}"
    }
  }
}
// 注:大括号{ }包裹的字段值内容为动态的,其余为固定参数。

请参考如下打印实例(基础模板+自定义区域)

{
    "cmd": "print",
    "requestID": "1hsi4aswim",
    "version": "1.0",
    "task": {
        "taskID": "MTP202507149kggx30wff0002",
        "projectId": "yiyao_b_b2c",
        "printer": "{printer_name}",
        "documents": [
            {
                "documentID": "DOC1",
                "contents": [
                    {
                        "data": {
                            "wmPoiId": 1287313,
                            "orderViewId": "31016683901398313391",
                            "waybillNo": "312008360717810",
                            "logisticsCompanyName": "中通",
                            "logisticsCompanyCode": "zhongtong",
                            "bagAddress": "上海分拨包",
                            "mark": "300 G096-00 B1",
                            "buyerRemark": "--买家备注--",
                            "merchantRemark": "--卖家备注--",
                            "wmPoiName": "杨豪多仓门店",
                            "payTime": "1751438282",
                            "extend": {
                                "stationCode": "L3",
                                "logisticsProductName": "电商标快",
                                "waybillFourthSegmentCode": "E通世界",
                                "labelAccountNo": "health-1711316-779517",
                                "proCode": "顺丰微小件",
                                "endType": "末",
                                "logisticsProductCode": "247",
                                "codingMapping": "WU",
                                "limitTypeCode": "T6",
                                "endName": "天成家园",
                                "proName": "顺丰特快",
                                "secondCode": "200-30",
                                "twoDimensionCode": "MMM={'k1':'028WL','k2':'028','k3':'','k4':'T6','k5':'SF1630018309610','k6':'A','k7':'d5a7053'}"
                            },
                            "stationCode": "L3",
                            "logisticsProductName": "电商标快",
                            "waybillFourthSegmentCode": "E通世界",
                            "labelAccountNo": "health-1711316-779517",
                            "proCode": "顺丰微小件",
                            "endType": "末",
                            "logisticsProductCode": "247",
                            "codingMapping": "WU",
                            "limitTypeCode": "T6",
                            "endName": "天成家园",
                            "proName": "顺丰特快",
                            "secondCode": "200-30",
                            "twoDimensionCode": "MMM={'k1':'028WL','k2':'028','k3':'','k4':'T6','k5':'SF1630018309610','k6':'A','k7':'d5a7053'}",
                            "actAmount": "81663.84",
                            "shippingAmount": "1.00",
                            "userInfo": {
                                "acctId": "114984347",
                                "wmPoiId": "1287313"
                            },
                            "printTime": "2025/7/14 11:29:41",
                            "senderName": "成都发货",
                            "senderPhone": "18872348765",
                            "senderAddress": "四川省成都市崇州市三江街道成都市发货测试地址",
                            "receiverName": "杨*",
                            "receiverPhone": "135****8310",
                            "receiverAddress": "北京市北京市朝阳区来广营地区北京市朝阳区北苑11号楼593室"
                        },
                        "templateURL": "https://s3plus.meituan.net/klfe-print/print/test/yiyao_b_b2c/c22e9d6ffffd9b4e087ad59be90771aa.json"
                    },
                    {
                        "data": {
                            "textStr1": "这是一个单行文本",
                            "textStr2": "这是一个三行文本 1<EOL>这是一个三行文本 2<EOL>这是一个三行文本 3",
                            "barcode": "0123456789"
                        },
                        "templateURL": "https://s3plus.meituan.net/klfe-print/print/test/lianruhe/46705899309c478a1ad6c841d2a6ebf6.json"
                    }
                ]
            }
        ],
        "customTags": {
            "printType": "WAYBILL",
            "appName": "com.sankuai.yiyaobb2cpf.merchant",
            "wmPoiId": "{门店ID}",
            "from": "{ERP名称,如:聚水潭/旺店通/XXX}"
        }
    }
}

字段解释:

字段名

类型

说明

是否必须

taskID

string

打印机任务ID,每个打印任务需要分配不同的且唯一的ID

notifyType

PrintTaskNotifyType[]

type PrintTaskNotifyType = 'render' | 'print';

打印通知类型:“render”, “print”
['render']:仅渲染完成通知
['print']:仅出纸完成通知
['render', 'print']:渲染完成、出纸完成后通知
[] : 不通知
注:如果 notifyType 没有指定,默认为 ['render', 'print']

preview

boolean

是否是预览

true:预览

false:打印

previewType

'pdf' | 'image'

预览模式,默认以 pdf 预览

printer

string

打印机名,如果为空,会使用系统默认打印机

pluginKey

string

业务插件标识

templateURL

string

模板文件 url

documents

array

文档数组,每项表示一个文档

documentID

string

文档的唯一ID,需要保证唯一

data

object

打印数据

 

响应:

{
  "cmd": "print",
  "requestID": "12345678901",
  "status": "success",
  "msg": "return nothing when success, return some tips when failed",
  "taskID":"1",
  "previewURL": "http://127.0.0.1/previewxxx.pdf",
  "previewImage": [
    "http://xxx.jpg"
  ]
}

字段解释:

此接口返回表示打印任务提交成功/失败,或预览文件生成成功/失败,并不表示打印成功/失败

字段名

类型

说明

taskID

string

打印机任务ID

previewURL

string

pdf 预览 URL

如果是预览并且预览模式是 previewType: 'pdf',会返回这个属性

previewImage

string[]

image 预览 URL

如果是预览并且预览模式是 previewType: 'image',会返回这个属性

 

2.4.5-1 模板语法(建议使用V2版本)

V1版本(不推荐):

{
    "canvasStyleData": {
        "width": 76,
        "height": 130,
        "pageScale": 1,
        "templateID": "1911d4a2-ced1-48a2-b7b9-276402abcd7c"
    },
    "componentData": [
        {
            "fixWdithHeight": false,
            "fixed": false,
            "group": "default",
            "isLock": false,
            "component": "p-qrcode",
            "label": "二维码",
            "icon": "erweima",
            "propValue": "1234567890",
            "style": {
                "rotate": 0,
                "opacity": 1,
                "width": 15,
                "height": 15,
                "top": 0,
                "left": 0
            },
            "belongAreaId": "9150f36d-700d-40bb-a97e-d6648d6314b0",
            "id": "0ab41d50-ddf1-4b79-829a-1352013919bb1646136915057"
        },
        {
            "fixWdithHeight": false,
            "fixed": false,
            "group": "default",
            "isLock": false,
            "component": "p-barcode",
            "label": "条形码",
            "icon": "tiaoxingma",
            "propValue": "1234567890",
            "style": {
                "rotate": 0,
                "opacity": 1,
                "width": 25,
                "height": 7,
                "top": 0,
                "left": 0
            },
            "belongAreaId": "9150f36d-700d-40bb-a97e-d6648d6314b0",
            "id": "31bd015f-b520-42b3-83e4-413b8eeff4da1646136915057"
        },
        {
            "fixWdithHeight": false,
            "fixed": false,
            "group": "default",
            "isLock": false,
            "component": "p-text",
            "label": "文字",
            "propValue": "单行文本",
            "icon": "wenben",
            "horizontallyScale": 1,
            "horizontally": "center",
            "vertical": "center",
            "style": {
                "rotate": 0,
                "opacity": 1,
                "width": 20,
                "height": 10,
                "fontSize": 4,
                "fontWeight": 500,
                "lineHeight": 4,
                "color": "",
                "top": 0,
                "left": 0
            },
            "belongAreaId": "9150f36d-700d-40bb-a97e-d6648d6314b0",
            "id": "38e8fd0c-7c6b-4e7e-8c39-e9e0e6b7ce8f1646136915057",
            "filedName": "test"
        },
        {
            "fixWdithHeight": false,
            "fixed": false,
            "group": "default",
            "isLock": false,
            "component": "p-qrcode",
            "label": "二维码",
            "icon": "erweima",
            "propValue": "1234567890",
            "style": {
                "rotate": 0,
                "opacity": 1,
                "width": 15,
                "height": 15,
                "errorLevel": "M",
                "version": 0,
                "top": 0,
                "left": 0
            },
            "belongAreaId": "9150f36d-700d-40bb-a97e-d6648d6314b0",
            "id": "5195aaa8-09ec-4fb6-852f-546197d5e0f71646136915057",
            "filedName": "qrcode"
        },
        {
            "fixWdithHeight": false,
            "fixed": false,
            "group": "default",
            "isLock": false,
            "component": "p-barcode",
            "label": "条形码",
            "icon": "tiaoxingma",
            "propValue": "1234567890",
            "style": {
                "rotate": 0,
                "opacity": 1,
                "width": 25,
                "height": 7,
                "top": 0,
                "left": 0
            },
            "belongAreaId": "9150f36d-700d-40bb-a97e-d6648d6314b0",
            "id": "77c6a86f-9032-4d38-a349-8646fc65a5231646136915057",
            "filedName": "code"
        },
        {
            "fixWdithHeight": false,
            "fixed": false,
            "group": "default",
            "isLock": false,
            "component": "p-rect-shape",
            "label": "矩形",
            "icon": "juxing",
            "style": {
                "rotate": 0,
                "opacity": 1,
                "width": 20,
                "height": 20,
                "borderTopWidth": 1,
                "borderTopStyle": "solid",
                "borderRightWidth": 1,
                "borderRightStyle": "solid",
                "borderBottomWidth": 1,
                "borderBottomStyle": "solid",
                "borderLeftWidth": 1,
                "borderLeftStyle": "solid",
                "top": 0,
                "left": 0
            },
            "belongAreaId": "9150f36d-700d-40bb-a97e-d6648d6314b0",
            "id": "392f18f0-fc6a-4dfc-8f25-843b2f0c77a91646136915057"
        },
        {
            "fixWdithHeight": false,
            "fixed": false,
            "group": "default",
            "isLock": false,
            "component": "p-line",
            "label": "线条",
            "icon": "xiantiao",
            "style": {
                "rotate": 0,
                "opacity": 1,
                "width": 25,
                "height": 0,
                "borderTopColor": "#000000",
                "borderTopWidth": 1,
                "borderTopStyle": "solid",
                "top": 110,
                "left": 5
            },
            "belongAreaId": "9150f36d-700d-40bb-a97e-d6648d6314b0",
            "id": "2f191ad3-a600-430c-a3e5-c5fdb93d85db1646136931603"
        },
        {
            "fixWdithHeight": false,
            "fixed": false,
            "group": "default",
            "isLock": false,
            "component": "p-picture",
            "label": "图片",
            "icon": "tupian",
            "propValue": "logo.png",
            "threshold": 0,
            "style": {
                "rotate": 0,
                "opacity": 1,
                "width": 15,
                "height": 10,
                "top": 0,
                "left": 0
            },
            "belongAreaId": "9150f36d-700d-40bb-a97e-d6648d6314b0",
            "id": "cc9c729e-b0e2-48c3-a9e3-1ddafa91ae2e1646138007292"
        }
    ]
}

V2版本(推荐):

完整组件 demo:http://portal-portm.meituan.com/test/klfe/print/template-demo.json,组件和字段说明见 2.4.5-2、2.4.5-3

{
  "component": "root",
  "type": "container",
  "editable": true,
  "templateVersion": "0.0.1",
  "languageVersion": "2.0.0",
  "docType": "label",
  "style": {
    "x": 0,
    "y": 0,
    "width": 76,
    "height": 130,
    "backgroundImage": ""
  },
  "children": [
    // 文本组件
    {
      "component": "text",
      "type": "basic",
      "writingMode": "lr",
      "style": {
        "x": 5,
        "y": 90,
        "width": 50,
        "rotation": 0,
        "textSize": 1,
        "textConfigsType": "character",
        "shift": "cutoff",
        "align": "left",
        "vertical": "middle",
        "fontFamily": "黑体",
        "EOL": "",
        "gap": 0,
        "textConfigs": [
          {
            "marginStart": 0,
            "marginEnd": 0,
            "width": 0,
            "fontScaleY": 1,
            "fontScaleX": 1,
            "substring": [
              0
            ],
            "isDelete": false,
            "isUnderline": false,
            "isBold": false
          }
        ]
      },
      "data": [
        {
          "value": "%{key}%",
          "type": "dynamic",
          "previewValue": "",
          "weight": 0,
          "prefix": "",
          "suffix": "",
          "overflow": ""
        }
      ]
    },
    // 二维码
    {
      "component": "qrcode",
      "type": "basic",
      "ecclevel": "M",
      "version": null,
      "mode": "A",
      "style": {
        "x": 5,
        "y": 100,
        "width": 20,
        "rotation": 0
      },
      "data": [
        {
          "value": "%{key}%",
          "type": "dynamic",
          "previewValue": ""
        }
      ]
    },
    // 条形码
    {
      "component": "barcode",
      "type": "basic",
      "codetype": "128",
      "style": {
        "x": 5,
        "y": 100,
        "width": 50,
        "height": 30,
        "rotation": 0
      },
      "data": [
        {
          "value": "%{key}%",
          "type": "dynamic",
          "previewValue": ""
        }
      ]
    },
    // 图片
    {
      "component": "image",
      "type": "basic",
      "style": {
        "x": 5,
        "y": 120,
        "height": 10,
        "width": 20
      },
      "data": [
        {
          "value": "%{key}%",
          "type": "dynamic",
          "previewValue": ""
        }
      ]
    },
    // 矩形
    {
      "component": "rectangle",
      "type": "basic",
      "style": {
        "x": 5,
        "y": 90,
        "width": 50,
        "height": 40,
        "rotation": 0,
        "borders": [
          {
            "width": 0.5,
            "style": "solid",
            "radius": 0
          },
          {
            "width": 0.5,
            "style": "solid",
            "radius": 0
          },
          {
            "width": 0.5,
            "style": "solid",
            "radius": 0
          },
          {
            "width": 0.5,
            "style": "solid",
            "radius": 0
          }
        ]
      }
    },
	// 线条
    {
      "component": "line",
      "type": "basic",
      "style": {
        "x": 30,
        "y": 110,
        "width": 30,
        "length": 0.3,
        "lineStyle": "solid",
        "color": "",
        "rotation": 0
      }
    }
  ]
}

2.4.5-2 组件汇总表

容器组件:根容器、布局容器、表格容器

扩展组件:子模板、富文本容器

基础组件:二维码、文本、线条、矩形、一维码、图片

组件类型

组件名称

描述

属性

描述(JSON)

模板信息组件

root(根容器)

 

兼容模式需要合并多个根容器

  • 用以描述整个标签的容器组件

  • 此容器为创建标签模板时自动生成

  • 此组件无数据字段

基础属性:

  • id

  • component

  • type

  • templateId

  • templateName

  • templateVersion

  • languageVersion

  • children

  • editable

  • docType

样式属性:

  • x

  • y

  • width

  • height

  • backgroundImage

代码块

Shell

 
{
  "component": "root",
  "type": "container",
  "templateId": "xxxxx",
  "templateName": "seller-new-city",
  "templateVersion": "0.0.1",
  "languageVersion": "2.0.0",
  "editable": true,
  "docType": "label",
  "style": {
    "x": 2,
    "y": 2,
    "width": 70,
    "height": 50,
    "backgroundImage": ""
  },
  "children": [...]
}

容器组件

layout(布局容器)

  • 相对定位容器,子元素均为绝对定位,性质同根容器,主要是用来嵌套分组

  • 必有子组件,才是有意义的标签模板

  • 此组件无数据字段

  • 子组件的x,y是相对于父组件的原点

基础属性:

  • id

  • component

  • type

  • childrn

  • editable

样式属性:

  • x

  • y

  • width

  • height

  • backgroundImage

代码块

Shell

 
{
  "component": "layout",
  "type": "container",
  "editable": true,
  "style": {
    "x": 2,
    "y": 2,
    "width": 70,
    "height": 50,
    "backgroundImage": ""
  },
  "children": [...]
}

table(表格)

  • 渲染表格结构(仅为表格结构样式渲染,不支持动态表格数据)

  • 只支持x*y的表格,不支持合并单元格,每行或者列的宽度必须一致(配置平台需校验)

  • 此组件无数据字段

基础属性:

  • id

  • component

  • type

  • tablelists

  • editable

样式属性:

  • x

  • y

  • borders

  • insideBorder

  • backgroundImage

代码块

Shell

 
{
  "component": "table",
  "type": "container",
  "style": {
    "x": 2,
    "y": 2,
    "backgroundImage": "",
    "borders": [{"width": 1}],
    "insideBorder": 2
  },
  "tablelists": [// 此为2 * 2的table
    [
      {
        "width": 20,
        "height": 30,
        "children": [...]
      },
      {
        "width": 20,
        "height": 30,
        "children": [...]
      }
    ],
    [
      {
        "width": 20,
        "height": 30,
        "children": [...]
      },
      {
        "width": 20,
        "height": 30,
        "children": [...]
      }
    ]
  ]
}

扩展组件

template(子模板)

  • 用以关联另一个模板嵌套,相当于iframe的能力

  • 该功能也可实现多个相同组件组合在一个完整模板的场景

  • 此组件无数据字段

  • 如果子模板和父组件根节点的宽高位置不兼容,需要平台校验,解析库按截断处理(以父模板配置为主)

基础属性:

  • id

  • component

  • type

  • templateId(关联本平台其它模板)

  • templateURL(关联到其它模板url地址)要校验格式

  • editable

样式属性:

  • x

  • y

  • width

  • height

代码块

Shell

 
{
  "component": "template",
  "type": "expand",
  "templateURL": "https://xxxxxxxx",
  "style": {
    "x": 2,
    "y": 2,
    "width": 20,
    "height": 30
  }
}

richtext(富文本)

  • 渲染模板结构

  • 其数据的value值为各种可扩展字符串

    数据只解析第一项

  • 指令解析的场景下,渲染为图片

  • templateContent 使用 loadash template 模板语法,参考文档: https://www.lodashjs.com/docs/lodash.template

 

前置传参解析函数

parser有个函数,业务传入此函数(此函数优先级比html高)

基础属性:

  • id

  • component

  • type

  • templateContent

  • editable

样式属性:

  • x

  • y

  • width

  • height

数据属性

代码块

Shell

 
{
  "component": "richtext",
  "type": "expand",
  "templateContent": "<h2><%=aaa%></h2>",
  "style": {
    "x": 2,
    "y": 2,
    "width": 20,
    "height": 30
  },
  "data": [
    {
      "value": "%templateData%",
      "type": "dynamic",
      "previewValue": { "aaa": "我是aaa" }
    }
  ]
}

基础组件

barcode(一维码)

  • 用以描述一维码的组件

  • 包含一维码特殊属性,每个bar的宽度等。

 

width 为一维码整体宽度,需要和codeType字段结合确定narrow和wide的宽度,且在模板配置平台需要增加最小宽度校验提示。

基础属性:

  • id

  • component

  • type

  • codetype

  • editable

样式属性:

  • x

  • y

  • width

  • height

  • rotation

数据属性

代码块

Shell

 
{
  "component": "barcode",
  "type": "basic",,
  "codetype": "128"
  "style": {
    "x": 2,
    "y": 2,
    "height": 10,
    "width": 10,
    "rotation": 0
  },
  "data": [
    {
      "value": "%packageCode%",
      "type": "dynamic",
      "previewValue": "xxxxxxxxxxxxx"
    }
  ]
}

qrcode(二维码)

  • 用以描述二维码的组件

  • 包含二维码特殊属性,纠错级别、版本等。

 

二维码配置平台配置动态宽高,单位mm,指令需要自己转成倍数

基础属性:

  • id

  • component

  • type

  • editable

  • ecclevel

  • version

  • mode

样式属性:

  • x

  • y

  • width

  • rotation

数据属性

代码块

Shell

 
{
  "component": "qrcode",
  "type": "basic",
  "ecclevel": "M",
  "version": 1,
  "mode": "A",
  "style": {
    "x": 2,
    "y": 2,
    "width": 20,
    "rotation": 0
  },
  "data": [
    {
      "value": "%packageCode%",
      "type": "dynamic",
      "previewValue": "xxxxxxxxxxxxx"
    }
  ]
}

text(文本)

  • 用以描述文本的组件

  • 可以描述文本行数,截断方式,拼接方式等

 

数据字段如果有weight,且互相不相同,则按截断计算数据,且截断后替换字符取overflow

如果没有weight,则每段的字符段处理shift

按行模式忽略substring字段,数组长度等于行数,按字符模式则数组长度可不等于行数,取substring字段

fontScale 控制字体大小,具体计算公式:scale*1.5*2*203/25.4 = xx px(打印的字体像素)

基础属性:

  • id

  • component

  • type

  • writingMode

样式属性:

  • x

  • y

  • width

  • rotation

  • vertical

  • align

  • shift

  • fontFamily

  • EOL

  • textSize

  • textConfigsType

  • textConfigs

数据属性

 

代码块

Shell

 
{
  "component": "text",
  "type": "basic",
  "writingMode": "lr",
  "style": {
    "x": 2,
    "y": 2,
    "width": 70,
    "rotation": 0,
    "textSize": 1,
    "textConfigsType": 'character',
    "vertical": "middle",
    "shift": "cutoff",
    "align": "left",
    "gap": 1,
    "EOL": "<EOL>",
    "textConfigs": [
        {
          "marginStart": 1,
          "marginEnd": 0,
          "width": 30,
          "fontScaleY": 1,
          "fontScaleX": 1,
          "substring": [0, -4],
          "isDelete": false,
          "isUnderline": false,
          "isBold": false
        },{
          "marginStart": 1,
          "marginEnd": 0,
          "width": 40,
          "fontScaleY": 1,
          "fontScaleX": 1,
          "substring": [-4, -1],
          "isDelete": false,
          "isUnderline": false,
          "isBold": false
        }
    ]
  },
  "data": [
      {
        "value": "%sign%",
        "type": "dynamic",
        "previewValue": "上",
        "weight": 2,
        "prefix": "[",
        "suffix": "]",
        "overflow": "" 
      }, {
        "value": "%threeCode%",
        "type": "dynamic",
        "previewValue": "A-C-305",
        "weight": 0,
        "overflow": "..."
      }, {
        "value": "%title%",
        "type": "dynamic",
        "previewValue": "我是xxx商铺",
        "overflow": ""
      }
    ]
}

text(国际化)

  • 用以描述国际化文本的组件

  • 可以描述文本行数字体

 

基础属性:

  • id

  • component

  • type

  • writingMode??

样式属性:

  • x

  • y

  • width

  • rotation

  • vertical

  • align

  • shift

  • fontFamily

  • EOL

  • textSize

  • textConfigsType

  • textConfigs

数据属性

 

代码块

 
{
  "component": "text",
  "type": "basic",
  "writingMode": "lr",
  "style": {
    "x": 2,
    "y": 2,
    "width": 70,
    "textSize": 1,
    "shift": "cutoff",
    "align": "left",
    "gap": 1,
    "textConfigs": [
        {
          "isBold": false
        }
    ]
  },
  "data": [
      {
        "value": "%sign%",
        "type": "dynamic",
        "previewValue": "上",
        "weight": 2
      }
    ]
}

 

line(线条)

  • 用以描述线条的组件

     

基础属性:

  • id

  • component

  • type

  • editable

样式属性:

  • x

  • y

  • width

  • length

  • rotation

  • lineStyle

代码块

Shell

 
{
  "component": "line",
  "type": "basic",
  "style": {
    "x": 2,
    "y": 2,
    "width": 20,
    "height": 2,
    "lineStyle": "solid"
  }
}

rectangle(矩形)

  • 用以描述矩形的组件

基础属性:

  • id

  • component

  • type

  • editable

样式属性:

  • x

  • y

  • width

  • height

  • borders

  • rotation

 

代码块

Shell

 
{
  "component": "rectangle",
  "type": "basic",
  "style": {
    "x": 2,
    "y": 2,
    "width": 20,
    "height": 10,
    "rotation": 0,
    "borders": [
      {
         "width": 1,
         "style": "solid",
         "radius": 0.5
      },
      {
         "width": 2,
         "style": "solid",
         "radius": 0.5
      },
      {
         "width": 3,
         "style": "dashed",
         "radius": 0.5
      }
    ]
  }
}

image(图片)

  • 用以描述图片的组件

  • 图片组件的数据字段值的类型可为:

    • 字符串(描述图片地址)

    • imageData(描述图片内容)

    • base64

  • 图片类型支持:png/jpg/webp

  • 数据只解析第一项

基础属性:

  • id

  • component

  • type

  • editable

样式属性:

  • x

  • y

  • width

  • height

数据属性

代码块

Shell

 
{
  "component": "image",
  "type": "basic",
  "style": {
    "x": 2,
    "y": 2,
    "height": 10,
    "width": 20
  },
  "data": [
    {
      "value": "%picUrl%",
      "type": "dynamic",
      "previewValue": "https://xxxxxxxxxxxxx.png"
    }
  ]
}

2.4.5-3 组件属性表

属性分组

属性名

含义

适用组件

类型

单位

默认值

可选值

基础属性

id

组件id

*

string

/

新建组件自动生成

 

docType

文档类型

root

string

/

'label'

  • label:标签

  • receipt:小票

  • invoice:单据

  • document:文档

component

组件名称

*

enum

/

无默认值,必传

  • root、layout、template、richtext

  • qrcode、text、line、rectangle、barcode、image

type

组件类型

*

enum

/

根据component自动生成

  • container、expand

  • basic

templateId

标签id

root

string

/

自动生成唯一值

 

templateURL

标签模板关联url

template

string

/

''

模板三方存放地址

templateName

标签别名

root

string

/

''

用户指定名称,自定义字段,校验是否当前项目下重复

templateVersion

标签版本

root

string (版本号规则)

/

'0.0.1'

默认自增,也可手动指定

languageVersion

语法版本

root

string (版本号规则)

/

'0.0.1'

'2.0.0'

children

子元素

all container

string

/

[]

此属性为容器组件自动生成

templateContent

富文本组件的模板内容

richtext

string

/

''

 

editable

该元素是否可编辑(不可继承)

*

boolean

/

true

 

tablelists

表格容器的行列信息描述。

此为二维数组,根据配置的行*列数,决定数组的长度。

table

数组内字段可配置:

属性

说明

类型

单位

默认

备注

width

宽度

number

mm

1

每个单元格的宽度,高度

同行的高度必须一致,同列的宽度必须一致

height

高度

number

mm

1

children

子元素

array

/

[]

子元素可以为非标签容器的任意其他组件

writingMode

文字方向,表示文字是横向书写,还是纵向书写

text

enum

/

'lr'

'tb' | 'lr'

codetype

一维条码种类

barcode

enum

/

'128' 暂时只支持CODE128

'128' | '128M' | 'EAN128' | '25' | '25C' | '39' | '39C' | '39S' | '93' | 'EAN13' | 'EAN13+2' | 'EAN13+5' | 'EAN8' | 'EAN8+2' | 'EAN8+5' | 'CODA' | 'UPCA' | 'UPCA+2' | 'UPCA+5' | 'UPCE' | 'UPCE+2' | 'UPCE+5' | 'CPOST' | 'MSI' | 'MSIC' | 'PLESSEY' | 'ITF14' | 'EAN14'

ecclevel

纠错级别

qrcode

enum

/

M

  • L:7%

  • M:15%

  • Q:25%

  • H:30%

version

二维码版本

qrcode

int

/

根据数据自动匹配

1-40

mode

二维码编码方式

qrcode

enum

/

'A'

  • 'A':自动编码

  • 'M': 手动编码

 

style

 

width

宽度

*

number

mm

必传

 

height

高度

root | layout | qrcode | barcode | image | rectangle | line

number

mm

必传

 

x

左上角x坐标

距离标签边缘绝对值

*

number

mm

0

 

y

左上角 Y 坐标

距离标签边缘绝对值

*

number

mm

0

 

backgroundImage

背景图,可以用来画水印或者整图

容器组件

string | imageData

/

''

  • imageData - canvas获取的未压缩图片数据

  • picUrl - 以http开头的远程图片

lineStyle

线条类型

line

enum

/

solid

  • solid 实线

  • dash 虚线

length

线条长度

line

number

mm

1

 

insideBorder

表格内部边框宽度

table

number

/

0.5

 

textSize

行数/列数

text

int

/

1

 

textConfigsType

下方text配置采取何种配置模式

按行模式忽略substring字段,数组长度等于行数,按字符模式则数组长度可不等于行数,取substring字段

text

enum

/

'line'

'character' | 'line'

vertical

竖向对齐方式

按行/列的最大高度/宽度为基线

text

enum

/

'middle'

'top' | 'middle' | 'bottom'

align

横向对齐方式

整体文本

text

enum

/

left

left

center

right

shift

截断方式

整体文本

text

enum

/

cutoff

cutoff 正常截断

ellipsis 截断,加省略号(下三点)

scale 缩放,以自适应文字框大小(按行不能配置scale)

gap

侧轴间距

text

number

mm

0

文字横向书写时此为上下边距

文字竖向书写时此为左右边距

fontFamily

字体定义

text

string

/

黑体

 

EOL

换行符

text

string

/

''

换行符标识

仅在按字符配置且配置数为1的情况下支持

textConfigs

此为一维数组,横轴为每行/每列的配置,纵轴为每行/每列拆分到字符的配置。

按行/字符配置样式,适用于多行/多列场景下,针对每行/每列/每个字符单独适配样式的场景(例如字体大小、宽度等)

 

 

text

字符可配置:

属性

说明

类型

单位

默认

备注

substring

该字符切分逻辑组

int[]

/

[0]

此默认值自动生成

fontScaleX

X轴字体大小

number

1

可支持小数,如果是指令生成文本传输,会默认向下取整(1-10)

非指令生成文本解析,具体计算公式:scale*1.5*2*203/25.4 = xx px(打印的字体像素)

fontScaleY

Y轴字体大小

number

1

marginStart

起点边距

number

mm

0

文字横向书写时此为左右边距

文字竖向书写时此为上下边距

marginEnd

终点边距

number

mm

0

width

宽度/高度

number

mm

此文本最大宽度/高度,按字符模式配置,此字段不使用

isDelete

是否有删除样式

boolean

/

false

 

isUnderline

是否有下划线

boolean

/

false

 

isBold

是否加粗

boolean

/

false

指令生成文本解析不支持该项实现

borders

边框信息,一维数组

rectangle | table

数组内字段可配置:

属性

说明

类型

单位

默认

备注

width

宽度

number

mm

0.5

边框宽度

style

样式

enum

/

top

solid | dashed

radius

圆角

number

mm

0

指令打印遇到此场景需要转图实现

1个元素代表所有边框配置,2个代表上下、左右、3个代表 上、左右、下,4个代表上,右,下,左(顺序同CSS规则)

四个边配置相同时,radius才生效

rotation

旋转角度

barcode

text

qrcode

enum

/

0

  • 0 不旋转

  • 90 顺时针旋转

  • 180

  • 270

 

data[i] 数组

value

数据填充字段key | 数据填充值

text | qrcode | barcode | image

string

/

'%%'

‘’

  • 当同级type = dynamic时,此字段为必填

type

数据类型

text | qrcode | barcode | image

enum

/

dynamic

  • dynamic 动态数据字段

  • fixed 静态数据字段

previewValue

数据填充值

text | qrcode | barcode | image

string

/

''

与 同级name 字段匹配

当同级type = dynamic时,只做DEMO示例字段展示

当同级type = fixed 时,渲染值取该值

prefix

该字段前方固定填充值

text

string

/

''

可以作为数据直接的拼接符号

suffix

该字段后方固定填充值

text

string

/

''

weight

字段拼接完整性优先级

text

int

/

0

  • 根据数组长度确定填充的值的上限范围,字段拼接按数组顺序,但是完整性是按此权重值,完整性优先级必须每个不同,若相同,则整体只做拼接。

  • 数据字段如果有weight,且互相不相同,则按截断计算数据,且截断后替换字符取overflow

    如果没有weight,则每段的字符段处理shift

overflow

数据超长截断的时候,在截断处增加替换字符

基础组件

string

/

''

 

2.4.6 打印通知(notifyPrintResult)

通知:

{
  "cmd": "notifyPrintResult",
  "printer": "打印机A",
  "taskID": "1",
  "taskStatus": "SUCCESS",
  "printStatus": [
    {
      "documentID": "9890000112011",
      "status": "SUCCESS",
      "msg": "if failed, some tips, if success ,nothing"
    }
  ]
}

字段解释:

字段名

类型

说明

printer

string

负责打印的打印机名称

taskID

string

任务ID,需要唯一的ID

taskStatus

string

任务状态:
FAILED : 失败;
RENDERED: 渲染完成
SUCCESS : 出纸完成

注:当打印出纸之后才会发送通知并且只通知一次

documentID

string

文档的唯一ID,需要保证唯一

status

string

文档状态

SUCCESS:成功;

FAILED:失败;

CANCELED:取消

(当一个任务中的一个文档打印失败,任务中其他的文档打印状态为“CANCELED”状态)

msg

string

如果任务状态为成功或挂起为空,如果任务状态为失败,则为失败原因概要

 

2.4.7 获取打印任务状态(getTaskStatus)

请求:

{
  "cmd": "getTaskStatus",
  "version": "1.0",
  "taskID": [
    "12311",
    "12312"
  ]
}

字段解释:

字段名

类型

说明

是否必须

taskID

string[]

打印机任务ID列表

响应:

{
  "cmd": "print",
  "requestID": "12345678901",
  "status": "success",
  "msg": "return nothing when success, return some tips when failed",
  "printStatus": [
    {
      "taskID": "12312",
      "status": "SUCCESS",
      "detailStatus": [
        {
          "documentID": "9890000112011",
          "status": "SUCCESS",
          "msg": "if failed ,some tips, if success or pending nothing",
          "printer": "打印机A"
        }
      ]
    }
  ]
}

字段解释:

字段名

类型

说明

taskID

string

打印机任务ID,每个打印任务会分配不同的且唯一的ID

documentID

string

文档的唯一ID,需要保证唯一

status

string

打印任务/文档状态

打印任务状态

'PENDING':等待中

'PRINTING':打印中

'CANCELED':已取消

'RENDERED':渲染完成

'SUCCESS':成功

'FAILED':失败


打印文档状态

'CANCELED':取消

'SUCCESS':成功

'FAILED':失败

msg

string

如果任务状态为成功或挂起为空,如果任务状态为失败,则为失败原因。

printer

string

负责打印的打印机名

 

2.4.8 打印任务状态变更通知(notifyTaskStatusUpdate)

通知:


{
  "cmd": "notifyTaskStatusUpdate",
  "printer": "打印机A",
  "queueStatus": "PRINTING",
  "taskList": [
    {
      "status": "SUCCESS",
      "taskID": "12312", 
      "documents": [
        {
          "documentID": "9890000112011",
          "status": "SUCCESS",
          "msg": "if failed ,some tips, if success or pending nothing",
          "printer": "打印机A"
        }
      ]
    }
  ]
}

字段解释:

字段名

类型

说明

printer

string

打印机名

queueStatus

'FREE' | 'PRINTING' | 'SUSPENDED'

打印队列状态

'FREE':空闲

'PRINTING':打印中

'SUSPENDED':暂停

status

string

打印任务/文档状态

taskID

string

打印机任务ID

documentID

string

文档的唯一ID,需要保证唯一

msg

string

如果任务状态为成功或挂起为空,如果任务状态为失败,则为失败原因概要。

 

三、开放平台对接

开放平台电子面单接入指南

【医药健康】B2C正式上线电子面单相关接口

主要交互流程