/** * [顺丰] 顺丰面单打印实例 * @typedef {Object} sf_express_instance * @property {string} version - 实例的版本号。 * @property {sf_express_instance_print_function} print - 打印信息的方法。 * @property {sf_express_instance_devices_function} devices - 获取打印机设备的方法。 */ /** * [顺丰] 打印信息的方法的类型定义。 * @callback sf_express_instance_print_function * @param {object} data - 要打印的数据。 * @param {Object} [options] - 打印选项(可选)。 * @param {'PRINT' | 'PREVIEW'} [options.lodopFn="PRINT"] - 打印类型。 * @param {boolean} [options.allPreview=false] - 预览全部面单 * @returns {Promise} */ /** * [顺丰] 打印设备的方法的类型定义。 * @callback sf_express_instance_devices_function * @param {string} [name] - 打印机名称前缀。 * @returns {Promise<{name: string; index: number}[]>} */ import {withResolvers} from '@/tools/object'; /** * 获取顺丰打印实例 * @param options * @param {string?} options.appid 合作伙伴编码(即顾客编码) * @param {string?} options.appname 打印机设备名称(即设备名称) * @param {'pro' | 'sbox'?} options.env 环境 * @returns {Promise} */ let sf_express = async function (options = {}) { const module = await import('@/libs/print/SCPPrint-2.7.1.js'); const {promise: load, resolve, reject} = withResolvers(); const instance = new module.default({ partnerID: options.appid || process.env.VUE_APP_SF_EXPRESS_APPID, env: options.env || process.env.VUE_APP_SF_EXPRESS_ENV || (process.env.NODE_ENV === 'development' ? 'sbox' : 'pro'), notips: false, callback(result) { if (result.code === 1) resolve(instance); else reject({code: result.code, message: result.msg}); }, }); try { const instance = await load; sf_express = () => Promise.resolve(instance); return instance; } catch (e) {} return instance; }; /** * * @type {sf_express_instance_print_function} */ export async function sf_express_print(data, options = {}, device) { const instance = await sf_express(options); if (device == null) { const {promise: loadDevices, resolve, reject} = withResolvers(); instance['getPrinters']((result) => { if (result.code === 1) { const devices = Array.isArray(result.printers) ? result.printers : []; resolve(devices); } else reject({message: result.msg, code: result.code}); }); const devices = await loadDevices; device = devices.find(device => device.name.startsWith(process.env.VUE_APP_SF_EXPRESS_APPNAME)); } if (device) instance['setPrinter'](device.index); return new Promise((resolve, reject) => { instance.print(data, ({code, msg}) => { if (code === 1) resolve() else reject({code, message: msg}); }); }); } let c_lodop = async function (options = {}) { const module = await import('@/libs/print/CLodop.js'); const instance = await module.default(options); c_lodop = () => Promise.resolve(instance); return instance; }; export async function getDevices() { const LODOP = await c_lodop(); return Array.from({length: LODOP['GET_PRINTER_COUNT']()}, (_, i) => { return { name: LODOP['GET_PRINTER_NAME'](`${i}`), driver: LODOP['GET_PRINTER_NAME'](`${i}:DriverName`), index: i, papers: LODOP['GET_PAGESIZES_LIST'](i, '\n').split('\n'), size: +LODOP['GET_PRINTER_NAME'](`${i}:PaperSize`), width: +LODOP['GET_PRINTER_NAME'](`${i}:PaperWidth`), height: +LODOP['GET_PRINTER_NAME'](`${i}:PaperLength`), dpi: +LODOP['GET_PRINTER_NAME'](`${i}:PrintQuality`), form: LODOP['GET_PRINTER_NAME'](`${i}:FormName`), }; }); } export async function getDevice(...priority) { const devices = await getDevices(); let device; for (let item of priority) { let command = []; if (typeof item === 'string') { const regex = /([^:;]+):+([^;]*)/g; let match; while ((match = regex.exec(item))) { const key = match[1].trim(); const value = match[2].trim(); if (key && value) command.push([key, value]); } } else { command = Object.entries(item); } device = devices.find(device => command.every(([key, value]) => { if (key === 'paper') return device['papers'].includes(value); if (key === 'width_mm' || key === 'height_mm') value *= 10; /* 传入 mm,比较的是 0.1mm */ return device[key] === value; })); if (device) break; } return device; } export default function (options = {}) { return c_lodop(options); }