const { v4 } =require('uuid');
const moment = require("moment");
const momenttimezone = require('moment-timezone');
const iconvLite = require('iconv-lite');
const querystring = require('querystring');
const path = require("path");
const { remote } = require("electron");
var qr = require('qr-image');
var fs = require('fs');
var JsBarcode = require('jsbarcode');
var big = require('big.js');
var childProcess = require('child_process');
const { exec } = childProcess;
const os = require('os');
const html2canvas = require("html2canvas");
const QRCode = require("qrcodejs2");
const diskInfo = require('node-disk-info');
const osUtils = require('os-utils');

/**
 * 将一个秒数值转换为  天:时:分:秒 格式
 * @param {*} time 表示秒数
 */
function calcParkingDuration(time) {
  var result = {
    Days: 0,
    Hours: 0,
    Minutes: 0,
    Seconds: 0,
  };
  if (!time) {
    return result;
  }

  var res = '';
  result.Days = Math.floor(time / (24 * 3600));
  time = time % (24 * 3600);

  result.Hours = Math.floor(time / 3600);
  time = time % 3600;

  result.Minutes = Math.floor(time / 60);
  time = Math.floor(time % 60);

  result.Seconds = time;
  return result;
}
/**
 * 将最小单位的金额转换成相应国家的基本单位。
 * @param {*} money
 */
function convertMoney(money, precision, defaultValue) {
  precision = parseInt(precision);
  if (isNaN(precision)) {
    precision = 2;
  }
  if (defaultValue == undefined) {
    defaultValue = 0;
  }
  money = parseFloat(money);
  if (isNaN(money) || money == null) {
    return defaultValue.toFixed(precision);
  }
  return (money / 100).toFixed(precision);
}

/**
 * 金额精确转换
 * @param money 金额（默认：分）
 * @param div 金额换算值
 * @param point 保留小数点后几位
 * @returns {string}
 */
function convertBigMoney(money,div = 100,point = 2) {
  return new big(money).div(div).toFixed(point);
}

/**
 * 金额汇率转换
 * @param money 金额
 * @param exchangeRate 汇率
 * @returns {*}
 */
function currencyMoney(money, exchangeRate) {
  return new big(money).times(parseFloat(exchangeRate)).toString();
}
/**
 * 序列化JSON对象,并格式化
 * @param {*} jsonObj
 */
function formatJson(jsonObj) {
  return JSON.stringify(jsonObj, ' ', 4);
}
/**
 * 将JSON对象转换为key1=value&key2=value&key3=value形式
 * @param {*} obj
 */
function jsonToQueryString(obj) {
  var toString = Object.prototype.toString;
  if (toString.call(obj) != '[object Object]') {
    return '';
  }
  return querystring.stringify(obj);
}
/**
 * 生成Guid
 * @param {*} style style: 表示Guid表示形式 1:小写字母+- 2:大写字母+- 3:纯小写字母 4:纯大写字母
 */
function guid(style) {
  if (style == undefined || style == null || isNaN(style)) {
    style = 1;
  }
  var strGuid = v4();
  if (style == 1) {
    return strGuid;
  } else if (style == 2) {
    return strGuid.toUpperCase();
  } else if (style == 3) {
    return strGuid.replace(/-/g, '');
  } else if (style == 4) {
    return strGuid.toUpperCase().replace(/-/g, '');
  } else {
    return strGuid;
  }
}
/**
 * 将Buffer转换为相应的字符串
 * @param {*} 字符编码(UTF-8、GBK、GB2312、GB18030)
 */
function bufferToString(bufferData, encoding) {
  if (
    !Buffer.isBuffer(bufferData) &&
    !Object.toString.call(bufferData) == '[object Array]'
  ) {
    return '';
  }
  if (!Buffer.isBuffer(bufferData)) {
    bufferData = Buffer.from(bufferData);
  }
  if (encoding.toUpperCase() == 'UTF-8') {
    return bufferData.toString();
  } else if (
    encoding.toUpperCase() == 'GBK' ||
    encoding.toUpperCase() == 'GB2312' ||
    encoding.toUpperCase() == 'GB18030'
  ) {
    return iconvLite.decode(bufferData, encoding);
  }
  if (iconvLite.encodingExists(encoding)) {
    return iconvLite.decode(bufferData, encoding);
  } else {
    throw new error(`解码失败,不支持解码:${encoding}数据`);
  }
}
/**
 * 将字符串内容转换为Buffer
 * @param {*} str 需要被转换为字符串的内容
 * @param {*} encoding 编码
 */
function stringToBuffer(str, encoding) {
  if (encoding == undefined || encoding == null) {
    encoding = 'UTF-8';
  }
  if (encoding == 'UTF-8') {
    return Buffer.from(str, encoding);
  } else {
    if (iconvLite.encodingExists(encoding)) {
      return iconvLite.encode(str, encoding);
    }
    else {
        throw new error(`编码失败,不支持的编码:${encoding}`);
    }
  }
}
/**
 * 将数据转换为base64字符串
 * @param {*} obj
 */
function bufferToBase64(obj) {
  var toString = Object.prototype.toString;
  if (
    Buffer.isBuffer(obj) ||
    Array.isArray(obj) ||
    toString.call(obj) == '[object Array]' ||
    toString.call(obj) == '[object String]'
  ) {
    return Buffer.from(obj).toString('base64');
  } else {
    return null;
  }
}
/**
 * 获取当前系统时间
 */
function currentTime() {
  return moment();
}
/**
 * 获取当前系统IP地址
 */
function getIP() {
  var os = require('os');
  var ifaces = os.networkInterfaces();
  for (var prop in ifaces) {
    for (var j = 0; j < ifaces[prop].length; j++) {
      var iface = ifaces[prop][j];
      if ('IPv4' !== iface.family || iface.internal !== false) {
        continue;
      }
      return iface.address;
    }
  }
}
/**
 * 获取当前树莓派系统温度
 * @param callback 回调
 */
function getRaspberryPiTemp(callback) {
  childProcess.exec('vcgencmd measure_temp',
      function (error, stdout) {
        if (error !== null) {
          console.log('获取当前树莓派系统温度出错:' + error);
          callback(stdout,error);
        } else {
          console.log("获取当前树莓派系统温度：" + stdout.replace('temp=',''));
          callback(stdout.replace('temp=',''),error);
        }
      })
}
/**
 * 获取当前树莓派系统电压
 * @param callback 回调
 */
function getRaspberryPiVolts(callback) {
  childProcess.exec('vcgencmd measure_volts core',
      function (error, stdout) {
        if (error !== null) {
          console.log('获取当前树莓派系统电压出错:' + error);
          callback(stdout,error);
        } else {
          console.log("获取当前树莓派系统电压：" + stdout.replace('volt=',''));
          callback(stdout.replace('volt=',''),error);
        }
      })
}
/**
 * 获取当前系统CPU型号
 * @param callback 回调
 */
function getSystemCpuTypeName(callback) {
  if (process.platform == "win32"){
    childProcess.exec('wmic cpu get name',{ encoding: 'binary' },
        function (error, stdout) {
          if (error !== null) {
            console.log('获取当前系统CPU型号出错:' + error);
            callback(stdout,error);
          } else {
            console.log("获取当前系统CPU型号：" + iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312'));
            callback(iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312').replace(/[\s\r\n]+$/, ""),error);
          }
        })
  } else if (process.platform == "linux" && process.arch == "arm") {
      childProcess.exec('cat /proc/cpuinfo | grep Hardware',
          function (error, stdout) {
              if (error !== null) {
                  childProcess.exec('strings /boot/start.elf | grep VC_BUILD_ID_BRANCH',
                      function (error, stdout) {
                          if (error !== null) {
                              console.log('获取当前系统CPU型号出错:' + error);
                              callback(stdout,error);
                          } else {
                              console.log("获取当前系统CPU型号：" + stdout.replace('VC_BUILD_ID_BRANCH: ','').replace('\n','').toUpperCase());
                              callback(stdout.replace('VC_BUILD_ID_BRANCH: ','').replace('\n','').replace(/[\s\r\n]+$/, "").toUpperCase())
                          }
                      }
                  )
              } else {
                  if (stdout) {
                      console.log("获取当前系统CPU型号：" + stdout.replace('Hardware\t: ','').replace('\n',''));
                      callback(stdout.replace('Hardware\t: ','').replace('\n','').replace(/[\s\r\n]+$/, ""),error);
                  }
              }
          })
  } else if (process.platform == "linux" && process.arch == "x64") {
      childProcess.exec('cat /proc/cpuinfo | grep "model name"',
          function (error, stdout) {
              if (error !== null) {
                  console.log('获取当前系统CPU型号出错:' + error);
                  callback(stdout,error);
              } else {
                  console.log("获取当前系统CPU型号：" + stdout.split('\n')[0].replace('model name\t: ','').replace('\n',''));
                  callback(stdout.split('\n')[0].replace('model name\t: ','').replace('\n','').replace(/[\s\r\n]+$/, ""),error);
              }
          })
  }
}
/**
 * 获取当前系统CPU序列号
 * @param callback 回调
 */
function getSystemCpuSerialNumber(callback) {
  if (process.platform == "win32"){
    childProcess.exec('wmic baseboard get serialnumber',{ encoding: 'binary' },
        function (error, stdout) {
          if (error !== null) {
            console.log('获取当前系统CPU序列号出错:' + error);
            callback(stdout,error);
          } else {
            console.log("获取当前系统CPU序列号：" + iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312'));
            callback(iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312').replace(/[\s\r\n]+$/, ""),error);
          }
        })
  } else if (process.platform == "linux" && process.arch == "arm") {
    childProcess.exec('cat /proc/cpuinfo | grep Serial',
        function (error, stdout) {
          if (error !== null) {
            console.log('获取当前系统CPU序列号出错:' + error);
            callback(stdout,error);
          } else {
            console.log("获取当前系统CPU序列号：" + stdout.replace('Serial\t\t: ','').replace('\n',''));
            callback(stdout.replace('Serial\t\t: ','').replace('\n','').replace(/[\s\r\n]+$/, ""),error);
          }
        })
  } else if (process.platform == "linux" && process.arch == "x64") {
      childProcess.exec('sudo dmidecode -t processor | grep "ID"',
          function (error, stdout) {
              if (error !== null) {
                  console.log('获取当前系统CPU序列号出错:' + error);
                  callback(stdout,error);
              } else {
                  console.log("获取当前系统CPU序列号：" + stdout.replace('\tID: ','').replace('\n',''));
                  callback(stdout.replace('\tID: ','').replace('\n','').replace(/[\s\r\n]+$/, ""),error);
              }
          })
  }
}
/**
 * 获取当前系统版本号
 * @param callback 回调
 */
function getSystemVersionNumber(callback) {
  if (process.platform == "win32"){
    childProcess.exec('ver',{ encoding: 'binary' },
        function (error, stdout) {
          if (error !== null) {
            console.log('获取当前系统版本号出错:' + error);
            callback(stdout,error);
          } else {
            console.log("获取当前系统版本号：" + iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312'));
            callback(iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312').replace(/[\s\r\n]+$/, ""),error);
          }
        })
  } else if (process.platform == "linux" && process.arch == "arm") {
    childProcess.exec('version.sh',
        function (error, stdout) {
          if (error !== null) {
            console.log('获取当前系统版本号出错:' + error);
            callback(stdout,error);
          } else {
            console.log("获取当前系统版本号：" + stdout.replace('\n',''));
            callback(stdout.replace('\n','').replace(/[\s\r\n]+$/, ""),error);
          }
        })
  } else if (process.platform == "linux" && process.arch == "x64") {
      childProcess.exec('lsb_release -a | grep Description',
          function (error, stdout) {
              if (error !== null) {
                  console.log('获取当前系统版本号出错:' + error);
                  callback(stdout,error);
              } else {
                  console.log("获取当前系统版本号：" + stdout.split('\n')[1].replace('Description:\t',''));
                  callback(stdout.split('\n')[1].replace('Description:\t',''),error);
              }
          })
  }
}
/**
 * 获取当前主板制造商
 * @param callback 回调
 */
function getMotherboardManufacturer(callback) {
  if (process.platform == "win32"){
    childProcess.exec('wmic bios get manufacturer',{ encoding: 'binary' },
        function (error, stdout) {
          if (error !== null) {
            console.log('获取当前主板制造商出错:' + error);
            callback(stdout,error);
          } else {
            console.log("获取当前主板制造商：" + iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312'));
            callback(iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312').replace(/[\s\r\n]+$/, ""),error);
          }
        })
  } else if (process.platform == "linux" && process.arch == "arm") {
    childProcess.exec('cat /proc/cpuinfo | grep Model',
        function (error, stdout) {
          if (error !== null) {
            console.log('获取当前系统版本号出错:' + error);
            callback(stdout,error);
          } else {
            console.log("获取当前系统版本号：" + stdout.replace('Model\t\t: ','').replace('\n',''));
            callback(stdout.replace('Model\t\t: ','').replace('\n','').replace(/[\s\r\n]+$/, ""),error);
          }
        })
  } else if (process.platform == "linux" && process.arch == "x64") {
    childProcess.exec('sudo lshw -short | grep -i system',
        function (error, stdout) {
          if (error !== null) {
            console.log('获取当前系统版本号出错:' + error);
            callback(stdout,error);
          } else {
            console.log("获取当前系统版本号：" + stdout.split('\n')[0].replace('system','').replace(/\s/g,''));
            callback(stdout.split('\n')[0].replace('system','').replace(/\s/g,'').replace(/[\s\r\n]+$/, ""),error);
          }
        })
  }
}
/**
 * 获取当前主板型号
 * @param callback 回调
 */
function getMotherboardModel(callback) {
  if (process.platform == "win32"){
    childProcess.exec('wmic baseboard get product',{ encoding: 'binary' },
        function (error, stdout) {
          if (error !== null) {
            console.log('获取当前主板型号出错:' + error);
            callback(stdout,error);
          } else {
            console.log("获取当前主板型号：" + iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312'));
            callback(iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312').replace(/[\s\r\n]+$/, ""),error);
          }
        })
  } else if (process.platform == "linux" && process.arch == "arm") {
    childProcess.exec('cat /proc/cpuinfo | grep Model',
        function (error, stdout) {
          if (error !== null) {
            console.log('获取当前主板型号出错:' + error);
            callback(stdout,error);
          } else {
            console.log("获取当前主板型号：" + stdout.replace('Model\t\t: ','').replace('\n',''));
            callback(stdout.replace('Model\t\t: ','').replace('\n','').replace(/[\s\r\n]+$/, ""),error);
          }
        })
  } else if (process.platform == "linux" && process.arch == "x64") {
      childProcess.exec('cat /proc/cpuinfo | grep "model name"',
          function (error, stdout) {
              if (error !== null) {
                  console.log('获取当前主板型号出错:' + error);
                  callback(stdout,error);
              } else {
                  console.log("获取当前主板型号：" + stdout.split('\n')[0].replace('model name\t: ','').replace('\n',''));
                  callback(stdout.split('\n')[0].replace('model name\t: ','').replace('\n','').replace(/[\s\r\n]+$/, ""),error);
              }
          })
  }
}
/**
 * 获取当前系统名称
 * @param callback 回调
 */
function getSystemOsName(callback) {
  if (process.platform == "win32"){
    childProcess.exec('wmic os get caption',{ encoding: 'binary' },
        function (error, stdout) {
          if (error !== null) {
            console.log('获取当前系统名称出错:' + error);
            callback(stdout,error);
          } else {
            console.log("获取当前系统名称：" + iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312'));
            callback(iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312').replace(/[\s\r\n]+$/, ""),error);
          }
        })
  } else if (process.platform == "linux") {
    childProcess.exec('cat /etc/os-release | grep ^ID=',
        function (error, stdout) {
          if (error !== null) {
            console.log('获取当前系统名称出错:' + error);
            callback(stdout,error);
          } else {
            console.log("获取当前系统名称：" + stdout.replace("ID=",'').replace("\n",''));
            callback(stdout.replace("ID=",'').replace("\n",'').replace(/[\s\r\n]+$/, ""),error);
          }
        })
  }
}
/**
 * 获取当前系统固件版本号
 *
 */
function getSystemFirmwareVersion () {
    return new Promise((resolve, reject) => {
        if (process.platform == "win32"){
            childProcess.exec('wmic os get version',{ encoding: 'binary' },
                function (error, stdout) {
                    if (error !== null) {
                        console.log('获取当前系统固件版本号出错:' + error);
                        resolve(stdout,error);
                    } else {
                        console.log("获取当前系统固件版本号：" + iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312'));
                        resolve(iconvLite.decode(new Buffer(stdout.split('\n')[1],'binary'),'gb2312').replace(/[\s\r\n]+$/, ""),error);
                    }
                })
        } else if (process.platform == "linux") {
            childProcess.exec('strings /boot/start.elf | grep VC_BUILD_ID_VERSION',
                function (error, stdout) {
                    if (error !== null) {
                        console.log('获取当前系统固件版本号出错:' + error);
                        resolve(stdout,error);
                    } else {
                        console.log("获取当前系统固件版本号：" + stdout.replace("VC_BUILD_ID_VERSION: ",'').replace("\n",''));
                        resolve(stdout.replace("VC_BUILD_ID_VERSION: ",'').replace("\n",'').replace(/[\s\r\n]+$/, ""),error);
                    }
                })
        }
    })
}
/**
 * 获取指定范围内的随机数
 * @param {*} min 最小数
 * @param {*} max 最大数
 */
function getRandom(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}
/**
 * 生成二维码图片(.png)
 * @param qrString 生成二维码文本
 * @param savePath 图片保存路径
 * @param imgName 图片名称
 * @param imgLevel 纠错级别（L,M,Q,H 默认M）
 * @param imgSize 图片大小(默认5)
 * @param imgMargin 二维码边框宽度（默认1）
 * @returns {Promise<unknown>}
 */
async function createQrCodeImg(qrString,savePath,imgName,imgLevel = 'M',imgSize = '5',imgMargin = '1') {
  return new Promise(function (resolve) {
    var code = qr.image(qrString, { ec_level: imgLevel,type: 'png', size: parseInt(`${imgSize}`),margin:parseInt(`${imgMargin}`) });
    if (!fs.existsSync(savePath)) {
      fs.mkdirSync(savePath);
    }
    //生成本地文件
    var pic = code.pipe(fs.createWriteStream(`${savePath}/${imgName}.png`));
    //监听错误事件
    pic.on('error', (err)=> {
      console.log(`二维码图片生成失败error：${err}`);
      resolve("");
    });
    //监听完成事件
    pic.on('finish', ()=> {
      let imgPath = path.join(savePath, `${imgName}.png`);
      console.log(`二维码图片生成成功，图片路径${imgPath}`);
      resolve(imgPath);
    });
  });
}
/**
 * 生成一维码图片（.png）
 * @param barString 生成一维码文本
 * @param savePath 图片保存路径
 * @param imgName 图片名称
 * @param barWidth 每个条条的宽度（默认2）
 * @param barHeight 整个条形码的高度（默认50）
 * @param barTextDisplay 是否显示条形码下面的文字（默认true）
 * @param barTextFontSize 设置条形码文本的字体大小（默认15）
 * @param barTextFontOptions 设置条形码文本的字体样式（默认：加粗）
 * @returns {Promise<unknown>}
 */
async function createBarCodeImg(barString,savePath,imgName,barWidth = '2',barHeight = '50',barTextDisplay = true,barTextFontSize = '15',barTextFontOptions = 'bold') {
  return new Promise(function (resolve) {
    var canvas = document.createElement("canvas");
    JsBarcode(canvas, barString, {
      width: barWidth,
      height: barHeight,
      displayValue: barTextDisplay,
      fontSize: barTextFontSize,
      fontOptions: barTextFontOptions
    });
    try {
      if (!fs.existsSync(savePath)) {
        fs.mkdirSync(savePath);
      }
      var str = canvas.toDataURL();
      var imgBase64Str = str.split(",")[1];
      var imageBuffer = Buffer.from(imgBase64Str, "base64");
      let imgPath = path.join(savePath, `${imgName}.png`);
      fs.writeFileSync(`${savePath}/${imgName}.png`, imageBuffer);
      console.log(`一维码图片生成成功，图片路径${imgPath}`);
      resolve(imgPath);
    } catch (err) {
      console.log(`一维码图片生成失败error:${err}`);
      resolve(err);
    }
  });
}

/**
 * 根据printObj参数生成png图片
 * @param printObj
                 picWidth: 580,//画布宽度
                 picHeight: 1000,//画布高度
                 startPrintX: 0,//每一行打印的开始位置(横坐标)
                 startPrintY: 30,//每一行打印的开始位置(纵坐标)
                 marginBottom: 12,//每一行之间的间隔高度。(可选)
                 footerHeight: 12,//小票底部留白高度。
                 fontStyle: 'normal',//normal | italic | oblique | inherit
                 fontWeight: 'normal',//normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit | auto
                 fontSize: 30,//字体大小(可选)
                 fontFamily: "Arial",//打印所需使用的字体(可选)
                 items: [
                   {
                      printText: "",//需要打印的文本(必填)
                      itemType: 1,//打印类型，1：文本 2：图片, 默认[1]。(可选)
                      align: 0,//对齐方式 0：居左 1：居中 2：居右,默认[0]。(可选)
                      startPrintX: 100,//从横坐标那个位置开始打印。(可选)
                      marginBottom: 0,//距离下一行的空白行的高度,默认[10](可选)
                      fontStyle: "",//字体样式,默认[正常](可选),可用的值：normal | italic | oblique | inherit
                      fontWeight: "",//是否加粗,默认[不加粗](可选),可用的值：normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit | auto
                      fontFamily: "",//字体类别,(可选)
                      fontSize: 0,//字体大小,默认20px(可选)
                    }
                 ]
 * @returns {Promise<unknown>}
 */
async function createPrintPNG(printObj) {
  return new Promise(async function (resolve) {
    var returnResult = {
      IsSuccess: false,
      Data: null,
      Message: ""
    };
    var printTemplate = {
      picWidth: 580,//画布宽度
      picHeight: 1000,//画布高度
      startPrintX: 0,//每一行打印的开始位置(横坐标)
      startPrintY: 30,//每一行打印的开始位置(纵坐标)
      marginBottom: 12,//每一行之间的间隔高度。(可选)
      footerHeight: 12,//小票底部留白高度。
      fontStyle: 'normal',//normal | italic | oblique | inherit
      fontWeight: 'normal',//normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit | auto
      fontSize: 30,//字体大小(可选)
      fontFamily: "Arial",//打印所需使用的字体(可选)
      printItems: [
        {
          printText: "",//需要打印的文本(必填)
          itemType: 1,//打印类型，1：文本 2：图片, 默认[1]。(可选)
          align: 0,//对齐方式 0：居左 1：居中 2：居右,默认[0]。(可选)
          startPrintX: 100,//从横坐标那个位置开始打印。(可选)
          marginBottom: 0,//距离下一行的空白行的高度,默认[10](可选)
          fontStytle: "",//字体样式,默认[正常](可选),可用的值：normal | italic | oblique | inherit
          fontWeight: "",//是否加粗,默认[不加粗](可选),可用的值：normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit | auto
          fontFamily: "",//字体类别,(可选)
          fontSize: 0,//字体大小,默认20px(可选)
        }
      ]
    };
    var canvas = document.createElement("canvas");
    var context = canvas.getContext("2d");
    context.fillStyle = "#FFFFFF";
    if (!printObj.hasOwnProperty("fontStyle")) {
      printObj.fontStyle = printTemplate.fontStyle;
    }
    if (!printObj.hasOwnProperty("fontWeight")) {
      printObj.fontWeight = printTemplate.fontWeight;
    }
    if (!printObj.hasOwnProperty("fontSize")) {
      printObj.fontSize = printTemplate.fontSize;
    }
    if (!printObj.hasOwnProperty("fontFamily")) {
      printObj.fontFamily = printTemplate.fontFamily;
    }
    if (!printObj.hasOwnProperty("marginBottom")) {
      printObj.marginBottom = printTemplate.marginBottom;
    }
    if (!printObj.hasOwnProperty("startPrintX")) {
      printObj.startPrintX = printTemplate.startPrintX;
    }
    if (!printObj.hasOwnProperty("startPrintY")) {
      printObj.startPrintY = printTemplate.startPrintY;
    }
    if (!printObj.hasOwnProperty("picWidth")) {
      printObj.picWidth = printTemplate.picWidth;
    }
    if (!printObj.hasOwnProperty("picHeight")) {
      printObj.picHeight = printTemplate.picHeight;
    }
    if (!printObj.hasOwnProperty("footerHeight")) {
      printObj.footerHeight = printObj.marginBottom;
    }
    canvas.width = printObj.picWidth;
    canvas.height = printObj.picHeight;
    var printX = printObj.startPrintX;
    var printY = printObj.startPrintY;
    for (var i = 0; i < printObj.items.length; i++) {
      var printItem = printObj.items[i];
      if (!printItem.hasOwnProperty("fontStyle")) {
        printItem.fontStyle = printObj.fontStyle;
      }
      if (!printItem.hasOwnProperty("fontWeight")) {
        printItem.fontWeight = printObj.fontWeight;
      }
      if (!printItem.hasOwnProperty("fontSize")) {
        printItem.fontSize = printObj.fontSize;
      }
      if (!printItem.hasOwnProperty("fontFamily")) {
        printItem.fontFamily = printObj.fontFamily;
      }
      if (!printItem.hasOwnProperty("marginBottom")) {
        printItem.marginBottom = printObj.marginBottom;
      }

      context.font = printItem.fontStyle + " " + printItem.fontWeight + " " + printItem.fontSize + "px" + " " + printItem.fontFamily;
      var textMetrics = context.measureText(printItem.printText);
      context.textAlign = 'left';
      if (printItem.align == '1') {//居中
        context.textAlign = 'center';
        printX = canvas.width / 2;
      } else if (printItem.align == '2') {//居右
        printX = (canvas.width - textMetrics.width - 20);
      } else {//居左
        if (printItem.hasOwnProperty("startPrintX")) {
          printX = printItem.startPrintX;
        } else {
          printX = printObj.startPrintX;
        }
      }
      await printItemBMP(context,canvas,printObj,printItem, printX, printY).then(res=>{
        //不把最后一样的行高+下边距算入画布高度。
        if (i < printObj.items.length - 1) {
          printY += printItem.marginBottom + res;
        } else {
          printY += 2;
        }
      });
    }
    printObj.picHeight = canvas.height + (printObj.footerHeight - (canvas.height - printY));
    setTimeout(function () {
      try {
        var str = canvas.toDataURL();
        var imgBase64Str = str.split(",")[1];
        var imageBuffer = Buffer.from(imgBase64Str, "base64");
        var filePath = path.resolve(path.join("./", "printImg.png"));
        fs.writeFileSync(filePath, imageBuffer)
        var pngFilePath = path.resolve(path.join("./", "printImgPNG.png"));
        var PNG = require("pngjs").PNG;
        fs.createReadStream(filePath)
            .pipe(new PNG({
              colorType: 0,
              bgColor: {
                red: 255,
                green: 255,
                blue: 255
              }
            }))
            .on('parsed', function () {
              try {
                this.pack().pipe(fs.createWriteStream(pngFilePath));
                setTimeout(function () {
                  returnResult.IsSuccess = true;
                  returnResult.Data = pngFilePath;
                  resolve(returnResult);
                },500)
              } catch (error) {
                returnResult.IsSuccess = false;
                returnResult.Message = error;
                resolve(returnResult);
              }
            });
      } catch (error) {
        console.log('PNG图片生成失败!');
        returnResult.IsSuccess = false;
        returnResult.Message = error;
        resolve(returnResult);
      }
    },500);
  })
}

/**
 *
 * @param printObj 打印内容
 *                   picWidth: 580,//画布宽度
                     picHeight: 1000,//画布高度
                     startPrintX: 0,//每一行打印的开始位置(横坐标)
                     startPrintY: 30,//每一行打印的开始位置(纵坐标)
                     marginBottom: 12,//每一行之间的间隔高度。(可选)
                     footerHeight: 12,//小票底部留白高度。
                     fontStyle: 'normal',//normal | italic | oblique | inherit
                     fontWeight: 'normal',//normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit | auto
                     fontSize: 30,//字体大小(可选)
                     fontFamily: "Arial",//打印所需使用的字体(可选)
                     items: [
                     {
                                          printText: "",//需要打印的文本(必填)
                                          itemType: 1,//打印类型，1：文本 2：图片, 默认[1]。(可选)
                                          align: 0,//对齐方式 0：居左 1：居中 2：居右,默认[0]。(可选)
                                          startPrintX: 100,//从横坐标那个位置开始打印。(可选)
                                          marginBottom: 0,//距离下一行的空白行的高度,默认[10](可选)
                                          fontStyle: "",//字体样式,默认[正常](可选),可用的值：normal | italic | oblique | inherit
                                          fontWeight: "",//是否加粗,默认[不加粗](可选),可用的值：normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit | auto
                                          fontFamily: "",//字体类别,(可选)
                                          fontSize: 0,//字体大小,默认20px(可选)
                                        }
                     ]
 * @param element DOM元素（可选，如果传入dom则直接使用传入的DOM内容
 * @returns {Promise<unknown>}
 */
async function createPrinterPng(printObj, element = "") {
  var returnResult = {
    IsSuccess: false,
    Data: null,
    Message: ""
  };
  return new Promise((resolve) => {
    printObj = printObj || {};
    let doc = window.top.document;
    const isEmpty = (obj) => Object.keys(obj).length === 0;
    // 当 printObj 含打印数据时 第二个参数传入 document
    if (!isEmpty(printObj) && element) {
      doc = element;
      element = null;
    }
    let id = element || "printHtml";
    let printHtml = (element && typeof element === 'string') ? doc.getElementById(id) : element;
    if(!element) {
      const dict = {
        0: "left",
        1: "center",
        2: "right"
      };
      printHtml = printHtml || doc.createElement("div");
      printHtml.innerHTML = "";
      printHtml.setAttribute("id", id);
      printObj.items = printObj.items.filter(item => item);
      let width = printObj.picWidth ? printObj.picWidth : '580';
      const ratio = window.devicePixelRatio || 1;
      let fz = printObj.fontSize / ratio || 28 / ratio;
      width = width / ratio;
      printHtml.setAttribute("style", `width:${width}px;font-size:${fz}px;background:#fff;color:#000;padding:${20/ratio}px;position:fixed;left:-2000px;padding-left:${printObj.startPrintX}px;padding-top:${printObj.startPrintY}px;${printObj.style||''}`);
      printObj.items.map((item) => {
        const align = dict[item.align] || item.align || "left";
        let bold = "normal";
        let italic = "normal";
        if (typeof item.bold === 'number' || typeof item.fontWeight === 'number') {
          bold = item.bold === 1 || item.fontWeight === 1 ? "bold" : "normal";
        }  else {
          bold = item.fontWeight;
        }
        if (typeof item.bold === 'number' || typeof item.fontWeight === 'number') {
          italic = item.italic === 1 || item.fontStyle === 1 ? "bold" : "normal";
        }  else {
          italic = item.fontStyle;
        }
        const printText = item.printText ? item.printText.trim() : "";

        let printItem = doc.createElement("div");
        if(item.qrCode || (printText && printText.indexOf("qrCode.jpg") !== -1)) {
          let qrWidth = item.width / ratio || 200 / ratio;
          let qrHeight = item.height / ratio || 200 / ratio;
          new QRCode(printItem, {
            text: printText || item.qrCode,
            width: qrWidth,
            height: qrHeight,
            colorDark: "#000", // 二维码颜色
            colorLight: "#fff", // 二维码背景色
            correctLevel: QRCode.CorrectLevel[item.level || "L"], // 容错率，L/M/H
          });
          printItem.setAttribute("style", `width:${qrWidth}px;margin:${20/ratio}px auto;${item.style||''}`);
        } else if(/\.(jpg|png|gif|bmp|jpeg)$/.test(printText) && fs.existsSync(printText)) {
          const img = doc.createElement("img");
          img.setAttribute("src", this.imgToBase64(printText));
          printItem.appendChild(img);
          printItem.setAttribute("style", `display:flex;justify-content:center;margin:${8/ratio}px 0;${item.style||''}`);
        } else {
          printItem.innerText = printText;
          let printStyle = `font-weight:${bold};font-style:${italic};text-align:${align};min-height:${30/ratio}px;margin-left:${item.startPrintX}px;font-size:${item.fontSize}px;${item.style||''}`;
          if(/^[.|#|=|*|-]*$/.test(item.printText)) {
            printStyle += 'white-space: nowrap;';
          } else {
            printStyle += 'white-space: normal;';
          }
          printItem.setAttribute("style", printStyle);
        }
        printHtml.appendChild(printItem);
      });
      doc.body.appendChild(printHtml);
    }
    html2canvas(printHtml, {
      allowTaint: true
    }).then(canvas => {
      let base64Data = canvas.toDataURL("image/png", 1.0).replace("data:image/png;base64,", "");
      const dataBuffer = Buffer.from(base64Data, "base64");
      const imagesDir = path.resolve(path.join("./"), "./printImg");
      const imagePath = path.join(imagesDir, "printImg.png");
      if (!fs.existsSync(imagesDir)) {
        fs.mkdirSync(imagesDir);
      }
      fs.promises.writeFile(imagePath, dataBuffer)
          .then(() => {
            console.log("打印图片生成成功:" + imagePath);
            returnResult.IsSuccess = true;
            returnResult.Data = imagePath;
            resolve(returnResult);
          })
          .catch((err) => {
            console.log("打印图片生成异常:" + err);
            returnResult.IsSuccess = false;
            returnResult.Message = err
            resolve(returnResult);
          })
    })
        .catch((err) => {
          console.log("打印图片生成异常:" + err);
          returnResult.IsSuccess = false;
          returnResult.Message = err
          resolve(returnResult);
        });
  });
}

/**
 * 根据printObj参数生成1位BMP图片
 * @param printObj   picWidth: 580,//画布宽度
                     picHeight: 1000,//画布高度
                     startPrintX: 0,//每一行打印的开始位置(横坐标)
                     startPrintY: 30,//每一行打印的开始位置(纵坐标)
                     marginBottom: 12,//每一行之间的间隔高度。(可选)
                     footerHeight: 12,//小票底部留白高度。
                     fontStyle: 'normal',//normal | italic | oblique | inherit
                     fontWeight: 'normal',//normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit | auto
                     fontSize: 30,//字体大小(可选)
                     fontFamily: "Arial",//打印所需使用的字体(可选)
                     items: [
                     {
                              printText: "",//需要打印的文本(必填)
                              itemType: 1,//打印类型，1：文本 2：图片, 默认[1]。(可选)
                              align: 0,//对齐方式 0：居左 1：居中 2：居右,默认[0]。(可选)
                              startPrintX: 100,//从横坐标那个位置开始打印。(可选)
                              marginBottom: 0,//距离下一行的空白行的高度,默认[10](可选)
                              fontStytle: "",//字体样式,默认[正常](可选),可用的值：normal | italic | oblique | inherit
                              fontWeight: "",//是否加粗,默认[不加粗](可选),可用的值：normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit | auto
                              fontFamily: "",//字体类别,(可选)
                              fontSize: 0,//字体大小,默认20px(可选)
                            }
                     ]
 * @returns {Promise<unknown>}
 */
async function createPrintBMP(printObj) {
  return new Promise(async function (resolve) {
    var returnResult = {
      IsSuccess: false,
      Data: null,
      Message: ""
    };
    var printTemplate = {
      picWidth: 580,//画布宽度
      picHeight: 1000,//画布高度
      startPrintX: 0,//每一行打印的开始位置(横坐标)
      startPrintY: 30,//每一行打印的开始位置(纵坐标)
      marginBottom: 12,//每一行之间的间隔高度。(可选)
      footerHeight: 12,//小票底部留白高度。
      fontStyle: 'normal',//normal | italic | oblique | inherit
      fontWeight: 'normal',//normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit | auto
      fontSize: 30,//字体大小(可选)
      fontFamily: "Arial",//打印所需使用的字体(可选)
      printItems: [
        {
          printText: "",//需要打印的文本(必填)
          itemType: 1,//打印类型，1：文本 2：图片, 默认[1]。(可选)
          align: 0,//对齐方式 0：居左 1：居中 2：居右,默认[0]。(可选)
          startPrintX: 100,//从横坐标那个位置开始打印。(可选)
          marginBottom: 0,//距离下一行的空白行的高度,默认[10](可选)
          fontStyle: "",//字体样式,默认[正常](可选),可用的值：normal | italic | oblique | inherit
          fontWeight: "",//是否加粗,默认[不加粗](可选),可用的值：normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit | auto
          fontFamily: "",//字体类别,(可选)
          fontSize: 0,//字体大小,默认20px(可选)
        }
      ]
    };
    var canvas = document.createElement("canvas");
    var context = canvas.getContext("2d");
    context.fillStyle = "#FFFFFF";
    if (!printObj.hasOwnProperty("fontStyle")) {
      printObj.fontStyle = printTemplate.fontStyle;
    }
    if (!printObj.hasOwnProperty("fontWeight")) {
      printObj.fontWeight = printTemplate.fontWeight;
    }
    if (!printObj.hasOwnProperty("fontSize")) {
      printObj.fontSize = printTemplate.fontSize;
    }
    if (!printObj.hasOwnProperty("fontFamily")) {
      printObj.fontFamily = printTemplate.fontFamily;
    }
    if (!printObj.hasOwnProperty("marginBottom")) {
      printObj.marginBottom = printTemplate.marginBottom;
    }
    if (!printObj.hasOwnProperty("startPrintX")) {
      printObj.startPrintX = printTemplate.startPrintX;
    }
    if (!printObj.hasOwnProperty("startPrintY")) {
      printObj.startPrintY = printTemplate.startPrintY;
    }
    if (!printObj.hasOwnProperty("width")) {
      printObj.width = printTemplate.picWidth;
    }
    if (!printObj.hasOwnProperty("height")) {
      printObj.height = printTemplate.picHeight;
    }
    if (!printObj.hasOwnProperty("footerHeight")) {
      printObj.footerHeight = printObj.marginBottom;
    }
    canvas.width = printObj.picWidth;
    canvas.height = printObj.picHeight;
    var printX = printObj.startPrintX;
    var printY = printObj.startPrintY;
    for (var i = 0; i < printObj.items.length; i++) {
      var printItem = printObj.items[i];
      if (!printItem.hasOwnProperty("fontStyle")) {
        printItem.fontStyle = printObj.fontStyle;
      }
      if (!printItem.hasOwnProperty("fontWeight")) {
        printItem.fontWeight = printObj.fontWeight;
      }
      if (!printItem.hasOwnProperty("fontSize")) {
        printItem.fontSize = printObj.fontSize;
      }
      if (!printItem.hasOwnProperty("fontFamily")) {
        printItem.fontFamily = printObj.fontFamily;
      }
      if (!printItem.hasOwnProperty("marginBottom")) {
        printItem.marginBottom = printObj.marginBottom;
      }

      context.font = printItem.fontStyle + " " + printItem.fontWeight + " " + printItem.fontSize + "px" + " " + printItem.fontFamily;
      var textMetrics = context.measureText(printItem.printText);
      context.textAlign = 'left';
      if (printItem.align == '1') {//居中
        context.textAlign = 'center';
        printX = canvas.width / 2;
      } else if (printItem.align == '2') {//居右
        printX = (canvas.width - textMetrics.width - 20);
      } else {//居左
        if (printItem.hasOwnProperty("startPrintX")) {
          printX = printItem.startPrintX;
        } else {
          printX = printObj.startPrintX;
        }
      }
      await printItemBMP(context,canvas,printObj,printItem, printX, printY).then(res=>{
        //不把最后一样的行高+下边距算入画布高度。
        if (i < printObj.items.length - 1) {
          printY += printItem.marginBottom + res;
        } else {
          printY += 2;
        }
      });
    }
    printObj.picHeight = canvas.height + (printObj.footerHeight - (canvas.height - printY));
    setTimeout(function () {
      var str = canvas.toDataURL();
      var imgBase64Str = str.split(",")[1];
      var imageBuffer = Buffer.from(imgBase64Str, "base64");
      var filePath = path.resolve(path.join("./", "printImg.png"));
      fs.writeFileSync(filePath, imageBuffer)
      var pngFilePath = path.resolve(path.join("./", "printImgPNG.png"));
      var Jimp = remote ? remote.require("jimp"):require("jimp");
      var PNG = require("pngjs").PNG;
      fs.createReadStream(filePath)
          .pipe(new PNG({
            colorType: 0,
            bgColor: {
              red: 255,
              green: 255,
              blue: 255
            }
          }))
          .on('parsed', function () {
            try {
              this.pack().pipe(fs.createWriteStream(pngFilePath));
              setTimeout(function () {
                Jimp.read(pngFilePath).then(function (image) {
                  image.getBuffer("image/bmp", function (error, buffer) {
                    const Bmp = require('binary-bmp');
                    const bit = 24; // 颜色位值
                    const width = printObj.picWidth; // 图片宽度
                    const height = printObj.picHeight; // 图片高度
                    const data = buffer;
                    const bmp = new Bmp(bit, { width, height, data });
                    var newBuffer = bmp.getBuffer();
                    fs.writeFileSync("./printImgBMP24.bmp",newBuffer);
                    var currentDir = __dirname;
                    var sdkPath = path.join(currentDir, "./windows/BMPGeneratorUtil.dll");
                    if (process.platform == "linux" && process.arch == "arm") {
                      sdkPath = path.join(currentDir, "./linux/BMPGeneratorUtil.so");
                    }
                    const ffi = remote ? remote.require("ffi-napi") : require("ffi-napi");
                    const ref = remote ? remote.require("ref-napi") : require("ref-napi");
                    const printerUtil = ffi.Library(sdkPath,{
                      BMP_bit24_to_uv1: [ref.types.bool, ["string","string"]],
                      JPG_To_BMP24: [ref.types.bool, ["string","string"]],
                      JPG_To_BMP1:  [ref.types.bool, ["string","string"]],
                    });
                    setTimeout(function () {
                      if (printerUtil.BMP_bit24_to_uv1(path.resolve(path.join("./", "printImgBMP24.bmp")),path.resolve(path.join("./", "printImgBMP1.bmp")))) {
                        console.log('24位BMP图片转1位BMP图片成功!');
                        var printImeFile = path.resolve(path.join("./", "printImgBMP1.bmp"));
                        returnResult.IsSuccess = true;
                        returnResult.Data = printImeFile;
                        resolve(returnResult);
                      }
                    },500);
                  });
                });
              }, 500);
            } catch (error) {
              console.log('24位BMP图片转1位BMP图片失败!');
              returnResult.IsSuccess = false;
              returnResult.Message = error;
              resolve(returnResult);
            }
          });
    },500);
  })
}

function printItemBMP(context,canvas,printObj,printItem, printX, printY) {
  return new Promise(resolve => {
    if (printItem.itemType == '2') {
      try {
        var image = new Image();
        const fs = require('fs');
        if (fs.existsSync(printItem.printText)) {
          fs.readFile(printItem.printText, 'base64', (err, data) => {
            image.src = 'data:image/png;base64,'+data;
            image.onload = function () {
              if (printItem.align == '1') {
                printX = ((canvas.width - image.width)/2);
              } else if (printItem.align == '2') {
                printX = (canvas.width - image.width - 20);
              } else {
                if (printItem.hasOwnProperty("startPrintX")) {
                  printX = printItem.startPrintX;
                } else {
                  printX = printObj.startPrintX;
                }
              }
              context.drawImage(image, printX, printY);
              resolve(image.height);
            }
          });
        } else {
          context.fillText(printItem.printText, printX, printY);
          resolve(0);
        }
      } catch (e) {
        console.log(e)
      }
    } else {
      context.fillText(printItem.printText, printX, printY);
      resolve(0);
    }
  })
}

/**
 * 图片转base64
 * @param imgPath
 * @returns {string}
 */
function imgToBase64(imgPath){
  const mineType = require('mime-types');
  let filePath = path.resolve(imgPath);
  let data = fs.readFileSync(filePath);
  data = new Buffer.from(data).toString('base64');
  let base64 = 'data:' + mineType.lookup(filePath) + ';base64,' + data;
  return base64;
}

/**
 * 从指定Url下载文件,并保存
 * @param {*} url 文件http地址
 * @param {*} savePath 保存位置
 */
async function downloadFile(url, savePath) {
  return new Promise(function (resolve) {
    let result = {
      success: false,
      message: '',
    };
    let fs = require('fs');
    if (url.startsWith('https')) {
      let https = require('https');
      let req = https.request(
        url,
        {
          rejectUnauthorized: false,
        },
        function (resp) {
          let stream = fs.createWriteStream(`${savePath}`);
          resp.pipe(stream);
          stream.on('finish', function () {
            result.success = true;
            stream.close();
            resolve(result);
          });
        }
      );
      req.on('error', function (error) {
        result.success = false;
        result.message = error.message;
        resolve(result);
      });
      req.end();
    } else if (url.startsWith('http')) {
      let http = require('http');
      let req = http.request(url, {}, function (resp) {
        let stream = fs.createWriteStream(`${savePath}`);
        resp.pipe(stream);
        stream.on('finish', function () {
          result.success = true;
          stream.close();
          resolve(result);
        });
      });
      req.on('error', function (error) {
        result.success = false;
        result.message = error.message;
        resolve(result);
      });
      req.end();
    } else {
      result.message = `下载失败,URL格式错误(仅支持http和https)`;
      resolve(result);
    }
  });
}


/**
 * 获取内存和硬盘信息
 */
function getStorageMessages() {
  return new Promise((resolve, reject) => {
    // 内存大小
    const totalMem = (os.totalmem() / 1024 / 1024 / 1024).toFixed(2) + 'G';
    // 硬盘大小
    if (process.platform == 'linux') {
      // 使用命令获取内存
      exec(`df -hl  `, (error, stdout) => {
        let hardDrive = '';
        if (error) {
          console.log(error);
          resolve({ totalMem, hardDrive });
          return;
        }
        const lines = stdout.split('\n');
        if (lines.length > 2) {
          const parts = lines[1].split(/\s+/);
          if (parts.length >= 2) {
            hardDrive = parts[1];
          }
        }
        resolve({ totalMem, hardDrive });
      });
    } else if (process.platform == 'win32') {
      // 使用命令获取内存
      exec(`wmic LogicalDisk where "Caption='C:'" get FreeSpace,Size /value  `, (error, stdout) => {
        let Size = stdout.replace(/\n|\r/g, '').substring(stdout.replace(/\n|\r/g, '').indexOf('Size='), stdout.replace(/\n|\r/g, '').length);
        Size = (Number(Size.replace('Size=', '')) / 1024 / 1024 / 1024).toFixed(2) + 'G';
        resolve({ totalMem, hardDrive: Size });
      });
    }
  });
}
/**
 * 系统时间信息(时区和时间差)
 */
function getTimeMessage() {
  const timeZone = momenttimezone.tz.guess(); // 自动检测时区
  const diffFromUTC = momenttimezone().utcOffset()+'min'; // UTC 时间差，单位为分钟
  return { timeZone, diffFromUTC };
}

/**
 * 获取网络信息 本机ip,子网掩码，网关，dns
 * @param {*} useLocalIp 在windows下因为可能存在多个ip的情况下需要指明需要哪个ip
 * @returns
 */
function getNetworkInfo(useLocalIp) {
  return new Promise((resolve, reject) => {
    let result = {
      ip_address: '',
      mask: '',
      routers: '',
      dns1: '',
      dns2: '',
    };
    // 在 Linux 系统上获取 DNS 配置信息
    if (os.platform() === 'linux') {
      exec('cat /etc/dhcpcd.conf', (err, stdout, stderr) => {
        if (err) {
          console.error('无法获取 DNS 配置信息:', err);
          resolve(result);
          return;
        }
        const lines = stdout.split('\n');
        lines.forEach((item) => {
          if (item.startsWith('static ip_address=')) {
            item = item.replace('static ip_address=', '');
            let strs = item.split('/');
            result.ip_address = strs[0];
            var interfaces = os.networkInterfaces()
            for (var devName in interfaces) {
               var iface = interfaces[devName]
               for (var i = 0; i < iface.length; i++) {
                   var alias = iface[i]
                   if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
                       result.mask = alias.netmask;
                   }
               }
            }
          }
          if (item.startsWith('static routers=')) {
            item = item.replace('static routers=', '');
            result.routers = item;
          }
          if (item.startsWith('static domain_name_servers=')) {
            item = item.replace('static domain_name_servers=', '');
            result.dns1 = item;
          }
          if (item.startsWith('static domain_search=')) {
            item = item.replace('static domain_search=', '');
            result.dns2 = item;
          }
        });
        resolve(result);
      });
    }
    // 在 Windows 系统上获取 DNS 配置信息
    if (os.platform() === 'win32') {
      const results = {
        ipAddresses: [],
        gateways: '',
        subnetMasks: [],
        dnsServers: [],
      };
      exec('ipconfig /all', { encoding: 'binary' }, (err, stdout, stderr) => {
        if (err) {
          console.error('无法获取 DNS 配置信息:', err);
          resolve(result);
          return;
        }
        stdout = iconvLite.decode(Buffer.from(stdout, 'binary'), 'gb2312');
        const lines = stdout.split('\r\n');
        let currentInterface = null;
        let twoDns = false;
        lines.forEach((line) => {
          line = line.trim();
          if (twoDns) {
            console.log('twoDns', line);
            if (/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/.test(line)) {
              results.dnsServers.push(line);
            }
          }
          twoDns = false;
          if (line.includes('适配器')) {
            currentInterface = line;
          } else if (currentInterface && line.includes('IPv4 地址')) {
            const ipAddress = line.split(':').pop().trim().replace('(首选)', '');
            results.ipAddresses.push(ipAddress);
          } else if (currentInterface && line.includes('子网掩码')) {
            const subnetMask = line.split(':').pop().trim();
            results.subnetMasks.push(subnetMask);
          } else if (currentInterface && line.includes('默认网关')) {
            const gateway = line.split(':').pop().trim();
            if (/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/.test(gateway)) {
              results.gateways = gateway;
            }
          } else if (currentInterface && line.includes('DNS 服务器')) {
            const dnsServers = line.split(':').pop().trim().split(/\s+/);
            let dnsServer = dnsServers.filter((item) => /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/.test(item));
            if (dnsServer && dnsServer.length > 0) {
              results.dnsServers.push(...dnsServer);
              twoDns = true;
            }
          }
        });

        if (useLocalIp) {
          for (let i = 0; i < results.ipAddresses.length; i++) {
            if (useLocalIp == results.ipAddresses[i]) {
              result.ip_address = results.ipAddresses[i];
              result.mask = results.subnetMasks[i];
            }
          }
        } else {
          if (results.ipAddresses[0]) {
            result.ip_address = results.ipAddresses[0];
            result.mask = results.subnetMasks[0];
          }
        }
        result.routers = results.gateways;
        if (results.dnsServers[0]) {
          result.dns1 = results.dnsServers[0];
        }
        if (results.dnsServers[1]) {
          result.dns2 = results.dnsServers[1];
        }
        resolve(result);
      });
    }
  });
}

/**
 * 终端信息采集 获取cpu，硬盘，内存使用率
 */
function termSysColl() {
  return new Promise((resolve, reject) => {
    try {
      diskInfo
        .getDiskInfo()
        .then((disks) => {
          let total = 0;
          let use = 0;
          disks.forEach((disk) => {
            total += disk._blocks;
            use += disk._used;
          });
          osUtils.cpuUsage(function (v) {
            let rest = {
              cpu: (v * 100).toFixed(2), //cpu使用率
              disk: ((use / total) * 100).toFixed(2), //硬盘使用率
              mem: ((1 - osUtils.freemem() / osUtils.totalmem()) * 100).toFixed(2), //内存使用率
            };
            resolve(rest);
          });
        })
        .catch((err) => {
          console.error('获取磁盘信息失败:', err);
        });
    } catch (err) {
      console.log(err);
      reject(err);
    }
  });
}
module.exports = {
  calcParkingDuration,
  convertMoney,
  formatJson,
  jsonToQueryString,
  guid,
  bufferToString,
  stringToBuffer,
  currentTime,
  getIP,
  getRaspberryPiTemp,
  getRaspberryPiVolts,
  getSystemCpuTypeName,
  getSystemCpuSerialNumber,
  getSystemVersionNumber,
  getMotherboardManufacturer,
  getMotherboardModel,
  getSystemOsName,
  getSystemFirmwareVersion,
  bufferToBase64,
  getRandom,
  printItemBMP,
  createQrCodeImg,
  createBarCodeImg,
  createPrintBMP,
  createPrintPNG,
  createPrinterPng,
  imgToBase64,
  downloadFile,
  getStorageMessages,
  getTimeMessage,
  getNetworkInfo,
  termSysColl
};
