微信小店打印组件前端web端对接

微信小店打印组件前端web端对接

1. 打印组件准备

插件下载地址:
Windows 64位下载链接
Windows 32位下载链接
Mac下载链接
注:如使用的是ISV打单或其他软件也需下载。
运营端使用指南:[https://store.weixin.qq.com/chengzhang/webdoc/wiki/544/6c826cffaccc0396/growth_center_manual_for_store?source=7&sourceType=4]

2. WebSocket对接

  1. 创建WebSocket, 建立web端和插件链接
  let waitingList = [], // 等待列表
   socket = null,// socket实例
   socketReady = false, // 是否开启监听了
   event = Event.getInstance() // 发布订阅模式封装的eventBus
  function start() {
    if (location.protocol.indexOf('https') >= 0) {
      socket = new WebSocket('ws://127.0.0.1:12705')
    } else if (location.protocol.indexOf('http') >= 0) {
      socket = new WebSocket('ws://127.0.0.1:12705')
    }
    // 打开Socket
   socket.onopen = e => {
      // 监听消息
      socketReady = true
      for (let index = 0, len = this.waitingList.length; index < len; index++) {
        const element = waitingList[index]
        socket.send(JSON.stringify(element))
      }
      waitingList = []
    }
    // 接收到Socket传输的消息
    socket.onmessage = e => {
      const response = JSON.parse(e.data)
      const cmd = response.command
      event.trigger(cmd, response) 
    }
    // 监听Socket的关闭
    socket.onclose = e => {
      this.socketReady = false
      // event.trigger('spSokcetClose', e) // 触发关闭监听, 需要注册监听  event.on('spSokcetClose', closeHandler)
      socket = null
    }
    // 监听Socket的报错
    socket.onerror = e => {
      this.socketReady = false
      // event.trigger('spSokcetError', e) // 触发错误监听, 需要注册监听  event.on('spSokcetError', errorHandler)
      socket = null
    }
  }

/**
* 发送方法封装
*/
 function send(request) {
    if (socketReady) {
      socket.send(JSON.stringify(request))
    } else {
      // 等待下次执行
      waitingList.push(request)
    }
    if (!socket) {
      // 没有初始化socket,初始化
      this.start()
    }
  }

获取打印机列表

  getPrinters() {
    const request = {
		requestID: '1234', // 自己生成请求的UUID
        command: 'getPrinterList'
	}
    return new Promise((resolve, reject) => {
      event.once('getPrinterList', function (res) {
        if (res.ret === 0) {
          resolve(res)
        } else {
          reject(res)
        }
      })
      send(request)
    })
  }

打印、预览面单

 function doPrintOrPreview(data, printer, preview = false){
   let request = {
		requestID: '1234', // 自己生成请求的UUID
		command: 'print'
	  }
    const { preview, printer } = params
    if (preview) {
      request.command = 'preview'
    }else {
      request.version = '2.0' // 打印必传
      request.printType = 2 // Number 打印类型,默认为 1,打印固定高度的面单;如果为2,则打印任意自定义内容,需要传递 size 参数指定纸张尺寸,printInfo 改为传递 base64 格式的 html
      request.size = {
        width: 76, // 纸张尺寸,单位毫米,printType 为 2 时必传,若是出现面单裁切或面单大小非130*76,则必须传入size
        height: 130,
      }
      request.printer = printer // 选中的打印机,printer.name
    }
    request.taskList = [] // 面单数据数组
    request.taskList.push({
      taskID: this._getUUID(8, 10), //String, 调用方保证唯一
      printInfo: '', // String, [获取打印报文]接口返回的print_info
      printNum: {
        curNum: 1, // 打印计数-当前张数
        sumNum: 1, // 打印计数-总张数
      },
      // 自定义模板信息,没有自定义模板需求可不传
      // 参考模板url:https://res.wx.qq.com/shop/public/2023-09-12/c39e49ba-9c0e-4912-91c1-5386fdd08f80.xml
      customInfo: {
        templateUrl, // 自定义模板url
        // 模板里面定义的数据字段
        data: {},
      },
      // 面单补充信息,用来覆盖寄件人信息,没有这种需求可以不传
      extendData: {},
    })

    return new Promise((resolve, reject) => {
      const handler = function (res) {
        if (res.requestID !== request.requestID) return
        if (res.command === 'preview') {
          // 预览
          if (res.previewUrl || res.previewImage) {
            let url
            if (res.previewUrl) {
              url = res.previewUrl
            } else if (res && res.previewImage) {
              url = res.previewImage
            }
            window.open(url)
            resolve(res)
          } else {
            reject(res)
          }
        } else {
          //打印
          // 失败结果
          const errResult = res.results.filter(item => !item.success)
          if (errResult.length === 0) {
            // 全部成功
            resolve(res)
            return
          }
          if (errResult.length === res.results.length && errResult.length > 0) {
            // 全部打印失败
            const err = new Error()
            err.message = '打印失败,失败原因:' + errResult[0].failureReason
            reject(err)
            return
          }
          // 部分失败
          const err = new Error()
          err.message =
            '部分运单打印失败,失败原因:' + errResult[0].failureReason
          reject(err)
        }
        event.off(cmd, handler)
      }
      event.on(cmd, handler)
      send(request)
    })
 }

event 发布订阅模式


export default class Event {
  /**
     * 构造函数,对象中新增eventHandlers对象存储事件处理器
     */
  constructor() {
    this.eventHandlers = {}
    return this
  }

  /**
     * 返回Event单例对象
     * @static
     * @returns Event Object
     * @memberof Event
     */
  static getInstance() {
    if (!this.Instance) {
      this.Instance = new Event()
    }
    return this.Instance
  }

  /**
     * 绑定事件监听器(订阅者)
     * @param {String} cmd 监听事件名称
     * @param {Function} handler 事件处理器
     * @memberof Event
     */
  on(cmd, handler) {
    if (typeof handler === 'function') {
      if (!this.eventHandlers[cmd]) {
        this.eventHandlers[cmd] = []
      }
      this.eventHandlers[cmd].push(handler)
    }
  }

  /**
     * 移除事件监听器(订阅者)
     * @param {String} cmd 监听事件名称
     * @param {Function} handler 事件处理器
     * @memberof Event
     */
  off(cmd, handler) {
    if (typeof handler === 'function') {
      if (this.eventHandlers[cmd].length > 0) {
        const handlerList = this.eventHandlers[cmd]
        const len = handlerList.length
        for (let index = 0; index < len; index++) {
          if (handlerList[index] === handler) {
            handlerList.splice(index, 1)
            if (handlerList.length === 0) {
              delete this.eventHandlers[cmd]
            }
            break
          }
        }
      }
    }
  }

  /**
     * 单词事件监听器
     * 执行完毕后移除对应事件监听器
     * @param {String} cmd 监听事件名称
     * @param {Function} handler 事件处理器
     * @memberof Event
     */
  once(cmd, handler) {
    if (typeof handler === 'function') {
      const cbfun = (...params) => {
        handler.apply(this, params)
        this.off(cmd, cbfun)
      }
      this.on(cmd, cbfun)
    }
  }

  /**
     * 事件触发器
     * 触发事件,顺序执行监听器
     * @param {*} cmd 监听事件名称
     * @param {*} params 传递给事件处理器的传参
     * @memberof Event
     */
  trigger(cmd, ...params) {
    if (!this.eventHandlers[cmd] || !this.eventHandlers[cmd].length) return
    const ctrl = this.eventHandlers[cmd]
    ctrl.forEach(item => {
      item.apply(this, params)
    })
  }

  /**
   * 清除一个事件上全部事件事件监听器
   * @param {Srting} cmd 事件名称
   */
  clear(cmd) {
    if (!this.eventHandlers[cmd]) return
    delete this.eventHandlers[cmd]
  }
}

打印、预览等使用示例参照官方:微信小店API

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值