print.tool.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /**
  2. * [顺丰] 顺丰面单打印实例
  3. * @typedef {Object} sf_express_instance
  4. * @property {string} version - 实例的版本号。
  5. * @property {sf_express_instance_print_function} print - 打印信息的方法。
  6. * @property {sf_express_instance_devices_function} devices - 获取打印机设备的方法。
  7. */
  8. /**
  9. * [顺丰] 打印信息的方法的类型定义。
  10. * @callback sf_express_instance_print_function
  11. * @param {object} data - 要打印的数据。
  12. * @param {Object} [options] - 打印选项(可选)。
  13. * @param {'PRINT' | 'PREVIEW'} [options.lodopFn="PRINT"] - 打印类型。
  14. * @param {boolean} [options.allPreview=false] - 预览全部面单
  15. * @returns {Promise<void>}
  16. */
  17. /**
  18. * [顺丰] 打印设备的方法的类型定义。
  19. * @callback sf_express_instance_devices_function
  20. * @param {string} [name] - 打印机名称前缀。
  21. * @returns {Promise<{name: string; index: number}[]>}
  22. */
  23. import {withResolvers} from '@/tools/object';
  24. /**
  25. * 获取顺丰打印实例
  26. * @param options
  27. * @param {string?} options.appid 合作伙伴编码(即顾客编码)
  28. * @param {string?} options.appname 打印机设备名称(即设备名称)
  29. * @param {'pro' | 'sbox'?} options.env 环境
  30. * @returns {Promise<sf_express_instance>}
  31. */
  32. let sf_express = async function (options = {}) {
  33. const module = await import('@/libs/print/SCPPrint-2.7.1.js');
  34. const {promise: load, resolve, reject} = withResolvers();
  35. const instance = new module.default({
  36. partnerID: options.appid || process.env.VUE_APP_SF_EXPRESS_APPID,
  37. env: options.env || process.env.VUE_APP_SF_EXPRESS_ENV || (process.env.NODE_ENV === 'development' ? 'sbox' : 'pro'),
  38. notips: false,
  39. callback(result) {
  40. if (result.code === 1) resolve(instance);
  41. else reject({code: result.code, message: result.msg});
  42. },
  43. });
  44. try {
  45. const instance = await load;
  46. sf_express = () => Promise.resolve(instance);
  47. return instance;
  48. } catch (e) {}
  49. return instance;
  50. };
  51. /**
  52. *
  53. * @type {sf_express_instance_print_function}
  54. */
  55. export async function sf_express_print(data, options = {}, device) {
  56. const instance = await sf_express(options);
  57. if (device == null) {
  58. const {promise: loadDevices, resolve, reject} = withResolvers();
  59. instance['getPrinters']((result) => {
  60. if (result.code === 1) {
  61. const devices = Array.isArray(result.printers) ? result.printers : [];
  62. resolve(devices);
  63. } else reject({message: result.msg, code: result.code});
  64. });
  65. const devices = await loadDevices;
  66. device = devices.find(device => device.name.startsWith(process.env.VUE_APP_SF_EXPRESS_APPNAME));
  67. }
  68. if (device) instance['setPrinter'](device.index);
  69. return new Promise((resolve, reject) => {
  70. instance.print(data, ({code, msg}) => {
  71. if (code === 1) resolve()
  72. else reject({code, message: msg});
  73. });
  74. });
  75. }
  76. let c_lodop = async function (options = {}) {
  77. const module = await import('@/libs/print/CLodop.js');
  78. const instance = await module.default(options);
  79. c_lodop = () => Promise.resolve(instance);
  80. return instance;
  81. };
  82. export async function getDevices() {
  83. const LODOP = await c_lodop();
  84. return Array.from({length: LODOP['GET_PRINTER_COUNT']()}, (_, i) => {
  85. return {
  86. name: LODOP['GET_PRINTER_NAME'](`${i}`),
  87. driver: LODOP['GET_PRINTER_NAME'](`${i}:DriverName`),
  88. index: i,
  89. papers: LODOP['GET_PAGESIZES_LIST'](i, '\n').split('\n'),
  90. size: +LODOP['GET_PRINTER_NAME'](`${i}:PaperSize`),
  91. width: +LODOP['GET_PRINTER_NAME'](`${i}:PaperWidth`),
  92. height: +LODOP['GET_PRINTER_NAME'](`${i}:PaperLength`),
  93. dpi: +LODOP['GET_PRINTER_NAME'](`${i}:PrintQuality`),
  94. form: LODOP['GET_PRINTER_NAME'](`${i}:FormName`),
  95. };
  96. });
  97. }
  98. export async function getDevice(...priority) {
  99. const devices = await getDevices();
  100. let device;
  101. for (let item of priority) {
  102. let command = [];
  103. if (typeof item === 'string') {
  104. const regex = /([^:;]+):+([^;]*)/g;
  105. let match;
  106. while ((match = regex.exec(item))) {
  107. const key = match[1].trim();
  108. const value = match[2].trim();
  109. if (key && value) command.push([key, value]);
  110. }
  111. } else {
  112. command = Object.entries(item);
  113. }
  114. device = devices.find(device => command.every(([key, value]) => {
  115. if (key === 'paper') return device['papers'].includes(value);
  116. if (key === 'width_mm' || key === 'height_mm') value *= 10; /* 传入 mm,比较的是 0.1mm */
  117. return device[key] === value;
  118. }));
  119. if (device) break;
  120. }
  121. return device;
  122. }
  123. export default function (options = {}) {
  124. return c_lodop(options);
  125. }