Parcourir la source

feat usb打印

Funny il y a 3 ans
Parent
commit
697ccd0dd2

+ 103 - 9
package-lock.json

@@ -1699,6 +1699,11 @@
       "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
       "dev": true
     },
+    "@types/semver": {
+      "version": "7.3.9",
+      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz",
+      "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ=="
+    },
     "@types/serve-static": {
       "version": "1.13.10",
       "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz",
@@ -5199,7 +5204,6 @@
       "version": "4.3.2",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
       "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
-      "dev": true,
       "requires": {
         "ms": "2.1.2"
       }
@@ -6180,6 +6184,90 @@
       "integrity": "sha512-QQUumrEjFDKSVYVdaeBmFdyQGoaV+fCSMyWHvfx/u22bRHSTeBQYt6P4jMY+gFd4kgKB9nqk7RMtWkDB49OYPA==",
       "dev": true
     },
+    "electron-updater": {
+      "version": "4.3.9",
+      "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.3.9.tgz",
+      "integrity": "sha512-LCNfedSwZfS4Hza+pDyPR05LqHtGorCStaBgVpRnfKxOlZcvpYEX0AbMeH5XUtbtGRoH2V8osbbf2qKPNb7AsA==",
+      "requires": {
+        "@types/semver": "^7.3.5",
+        "builder-util-runtime": "8.7.5",
+        "fs-extra": "^10.0.0",
+        "js-yaml": "^4.1.0",
+        "lazy-val": "^1.0.4",
+        "lodash.escaperegexp": "^4.1.2",
+        "lodash.isequal": "^4.5.0",
+        "semver": "^7.3.5"
+      },
+      "dependencies": {
+        "argparse": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+          "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+        },
+        "builder-util-runtime": {
+          "version": "8.7.5",
+          "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.5.tgz",
+          "integrity": "sha512-fgUFHKtMNjdvH6PDRFntdIGUPgwZ69sXsAqEulCtoiqgWes5agrMq/Ud274zjJRTbckYh2PHh8/1CpFc6dpsbQ==",
+          "requires": {
+            "debug": "^4.3.2",
+            "sax": "^1.2.4"
+          }
+        },
+        "fs-extra": {
+          "version": "10.0.0",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
+          "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+          "requires": {
+            "graceful-fs": "^4.2.0",
+            "jsonfile": "^6.0.1",
+            "universalify": "^2.0.0"
+          }
+        },
+        "js-yaml": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+          "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+          "requires": {
+            "argparse": "^2.0.1"
+          }
+        },
+        "jsonfile": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+          "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+          "requires": {
+            "graceful-fs": "^4.1.6",
+            "universalify": "^2.0.0"
+          }
+        },
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "semver": {
+          "version": "7.3.5",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+          "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        },
+        "universalify": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+          "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+        }
+      }
+    },
     "element-ui": {
       "version": "2.15.6",
       "resolved": "https://registry.npmjs.org/element-ui/-/element-ui-2.15.6.tgz",
@@ -7670,8 +7758,7 @@
     "graceful-fs": {
       "version": "4.2.8",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
-      "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
-      "dev": true
+      "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg=="
     },
     "graceful-readlink": {
       "version": "1.0.1",
@@ -9206,8 +9293,7 @@
     "lazy-val": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
-      "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==",
-      "dev": true
+      "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q=="
     },
     "levn": {
       "version": "0.3.0",
@@ -9370,6 +9456,16 @@
       "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
       "dev": true
     },
+    "lodash.escaperegexp": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
+      "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c="
+    },
+    "lodash.isequal": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+      "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
+    },
     "lodash.kebabcase": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
@@ -9861,8 +9957,7 @@
     "ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
     },
     "multicast-dns": {
       "version": "6.2.3",
@@ -12461,8 +12556,7 @@
     "sax": {
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
-      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
-      "dev": true
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
     },
     "schema-utils": {
       "version": "2.7.1",

+ 1 - 0
package.json

@@ -19,6 +19,7 @@
     "@amap/amap-vue": "^2.0.13",
     "axios": "^0.24.0",
     "core-js": "^3.19.0",
+    "electron-updater": "^4.3.9",
     "element-ui": "^2.15.6",
     "moment": "^2.29.1",
     "qrcodejs2": "0.0.2",

+ 2 - 7
src/App.vue

@@ -94,24 +94,19 @@ export default {
     usbPrint(orderId, waimaiOrderId, orderType) {
       // usb自动打印新订单、预约单
       getPrintOrderInfos({ orderId, waimaiOrderId }).then((res) => {
-        console.log("返回内容:", res);
+        // console.log("返回内容:", res);
         if (res.code === 200 && res.data) {
           let data = res.data;
           this.printData = data;
           this.orderType = orderType;
           this.printNum += 1;
-          // let len = this.printList.length;
-          // this.printList = this.printList.concat(res.data);
-          // if (!len) {
-          //   this.printOver(false);
-          // }
         }
       });
     },
     getSoundMsg() {
       getSoundMsg().then((res) => {
         if (res.code === 200) {
-          console.log("提示音:", res.data);
+          // console.log("提示音:", res.data);
           if (res.data) {
             let data = res.data;
             let name = data.sound.slice(0, data.sound.indexOf("."));

+ 8 - 0
src/api/shop.js

@@ -135,3 +135,11 @@ export const deviceDelete = (params) => {
 export const deviceStatus = (params) => {
   return get('app/shop/device/status', params)
 }
+// 添加USB打印机
+export const addUsbPrint = (params) => {
+  return post('app/shop/device/addUsbPrint', params)
+}
+// 获取USB打印机
+export const getUsbPrint = (params) => {
+  return get('app/shop/device/getUsbPrint', params)
+}

+ 54 - 0
src/background.js

@@ -5,6 +5,60 @@ import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
 import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
 const path = require('path')
 const isDevelopment = process.env.NODE_ENV !== 'production'
+// 注意这个autoUpdater不是electron中的autoUpdater
+import { autoUpdater } from "electron-updater"
+// 更新服务器地址,比如"http://**.**.**.**:3002/download/"
+import config from "../vue.config";
+let uploadUrl = config.pluginOptions.electronBuilder.builderOptions.publish[0].url
+// 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写
+function updateHandle() {
+  let message = {
+    error: '检查更新出错',
+    checking: '正在检查更新……',
+    updateAva: '检测到新版本,正在下载……',
+    updateNotAva: '现在使用的就是最新版本,不用更新',
+  };
+  const os = require('os');
+
+  autoUpdater.setFeedURL(uploadUrl);
+  autoUpdater.on('error', function (error) {
+    sendUpdateMessage(message.error)
+  });
+  autoUpdater.on('checking-for-update', function () {
+    sendUpdateMessage(message.checking)
+  });
+  autoUpdater.on('update-available', function (info) {
+    sendUpdateMessage(message.updateAva)
+  });
+  autoUpdater.on('update-not-available', function (info) {
+    sendUpdateMessage(message.updateNotAva)
+  });
+
+  // 更新下载进度事件
+  autoUpdater.on('download-progress', function (progressObj) {
+    mainWindow.webContents.send('downloadProgress', progressObj)
+  })
+  autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
+    ipcMain.on('isUpdateNow', (e, arg) => {
+      console.log(arguments);
+      console.log("开始更新");
+      //some code here to handle event
+      autoUpdater.quitAndInstall();
+    });
+
+    mainWindow.webContents.send('isUpdateNow')
+  });
+
+  ipcMain.on("checkForUpdate", () => {
+    //执行自动更新检查
+    autoUpdater.checkForUpdates();
+  })
+}
+
+// 通过main进程发送事件给renderer进程,提示更新信息
+function sendUpdateMessage(text) {
+  mainWindow.webContents.send('message', text)
+}
 
 // Scheme must be registered before the app is ready
 protocol.registerSchemesAsPrivileged([

+ 15 - 3
src/common/UsbAutoPrint.vue

@@ -48,6 +48,7 @@
 
 <script>
 import { getLodop } from "./LodopFuncs.js";
+import { mapGetters } from "vuex";
 export default {
   name: "UsbAutoPrint",
   // orderType: 1, // 1是新订单2是取消单
@@ -57,10 +58,13 @@ export default {
       printInfo: {},
       num: 1,
       pageWidth: 1, //1是57mm、2是80mm
+      usbPrinterList: [],
     };
   },
   // 监听属性 类似于data概念
-  computed: {},
+  computed: {
+    ...mapGetters(["usbPrinter"]),
+  },
   // 监控data中的数据变化
   watch: {
     printNum: {
@@ -72,6 +76,14 @@ export default {
         }
       },
     },
+    usbPrinter: {
+      handler(newVal, oldVal) {
+        console.log('newVal',newVal);
+        this.usbPrinterList = newVal;
+      },
+      deep: true,
+      immediate: true,
+    },
   },
 
   // 生命周期 - 创建完成(可以访问当前this实例)
@@ -104,9 +116,9 @@ export default {
       LODOP = getLodop();
       LODOP.PRINT_INIT("订单小票");
       //选择操作系统中设为“默认”的打印机,“-1”代表默认打印机
-      LODOP.SET_PRINTER_INDEX(-1);
+      LODOP.SET_PRINTER_INDEX(priterName);
       //设置打印份数是1份
-      LODOP.SET_PRINT_COPIES(1);
+      LODOP.SET_PRINT_COPIES(printerCount);
       // 参数含义 http://www.c-lodop.com/demolist/PrintSample5.html
       if (this.pageWidth === 1) {
         LODOP.SET_PRINT_PAGESIZE(3, 570, 100, "");

+ 1 - 1
src/components/shopCompoents/bindPrinter.vue

@@ -9,7 +9,7 @@
           <div class="b_line"></div>
           <div class="triangle"></div>
         </div>
-        <div class="label">打印机管理</div>
+        <div class="label">打印机管理</div>
       </div>
       <div class="right">
         <el-button class="btn" @click.stop="addPrinter(1)">添加打印机</el-button>

+ 447 - 0
src/components/shopCompoents/bindUsbPrint.vue

@@ -0,0 +1,447 @@
+<template>
+  <div class="shopAdd">
+    <div class="header">
+      <div class="left">
+        <div class="head-line">
+          <div class="b_line"></div>
+          <div class="triangle"></div>
+        </div>
+        <div class="label">USB打印机管理</div>
+      </div>
+    </div>
+    <div class="printer-list">
+      <div class="printer" @click="setPinter(i)" v-for="(v,i) in printerList" :key="i">
+        <div :class="v.status ? 'img-wrap online-bg' : 'img-wrap offline-bg' ">
+          <img :src="v.status ? require('../../../static/image/usb-online.png') : require('../../../static/image/usb-offline.png')" alt="">
+        </div>
+        <div class="name">{{v.deviceName}}</div>
+      </div>
+    </div>
+    <!-- 打印机新增、编辑 -->
+    <el-dialog width="40%" :title="title" destroy-on-close center :visible.sync="showVisible">
+      <el-form :model="form" ref="form" label-width="130px">
+        <el-form-item label="打印机系统名称" prop="deviceName">
+          <span>{{form.deviceName}}</span>
+        </el-form-item>
+        <el-form-item label="打印机自定义名称" prop="name">
+          <el-input v-model="form.name" placeholder="给这台打印机取个名字吧" autocomplete="off" style="width: 100%">
+          </el-input>
+        </el-form-item>
+        <el-form-item label="自动打印接单" prop="deviceSecret">
+          <el-switch v-model="form.openOrderPrint" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
+        </el-form-item>
+        <el-form-item label="自动打印取消单" prop="deviceSecret">
+          <el-switch v-model="form.openOrderCancelPrint" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
+        </el-form-item>
+        <el-form-item label="打印份数">
+          <div class="printer-num">
+            <img @click="reduce(1)" src="../../../static/image/icon_reduce.png" class="reduce" alt="" srcset="" />
+            <div class="num">{{ form.printCustomerCount }} 份</div>
+            <img @click="add(1)" src="../../../static/image/icon_add.png" class="add" alt="" srcset="" />
+            <div class="name">客户联</div>
+          </div>
+          <div class="printer-num">
+            <img @click="reduce(2)" src="../../../static/image/icon_reduce.png" class="reduce" alt="" srcset="" />
+            <div class="num">{{ form.printMerchantCount }} 份</div>
+            <img @click="add(2)" src="../../../static/image/icon_add.png" class="add" alt="" srcset="" />
+            <div class="name">商家联</div>
+          </div>
+          <div class="printer-num">
+            <img @click="reduce(3)" src="../../../static/image/icon_reduce.png" class="reduce" alt="" srcset="" />
+            <div class="num">{{ form.printKitchenCount }} 份</div>
+            <img @click="add(3)" src="../../../static/image/icon_add.png" class="add" alt="" srcset="" />
+            <div class="name">厨房联</div>
+          </div>
+        </el-form-item>
+        <el-form-item label="小票宽度" prop="width">
+          <el-radio-group v-model="form.width">
+            <el-radio :label="58">58mm</el-radio>
+            <el-radio :label="80">80mm</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="启用USB打印机" prop="status">
+          <el-switch v-model="form.status" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
+        </el-form-item>
+        <el-form-item>
+          <span @click="printTest" class="print-test">打印测试</span>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button :loading="loading" size="medium" class="btn" @click="save">保存</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { addUsbPrint, getUsbPrint } from "../../api/shop.js";
+import { getLodop } from "../../common/LodopFuncs.js";
+import { mapState, mapMutations, mapGetters } from "vuex";
+export default {
+  name: "bindUsbPrint",
+  props: {
+    devices: {
+      type: Array,
+      default: function () {
+        return [];
+      },
+    },
+  },
+  data() {
+    return {
+      title: "设置USB打印机",
+      showVisible: false,
+      form: {},
+      revieweds: [],
+      loading: false,
+      isEdit: false,
+      printerList: [],
+      dataList: [],
+      form: {},
+    };
+  },
+  created() {},
+  mounted() {
+    this.getUsbPrint();
+  },
+  methods: {
+    ...mapMutations(["SET_USBPRINTER"]),
+    printTest() {
+      setTimeout(() => {
+        LODOP = getLodop();
+        LODOP.PRINT_INIT("测试打印");
+        LODOP.SET_PRINT_PAGESIZE(3, this.form.width * 10, 100, "");
+        LODOP.SET_PRINTER_INDEX(this.form.deviceName);
+        LODOP.ADD_PRINT_TEXT(60, 20, 500, 125, "该打印机可以正常打印!");
+        LODOP.SET_PRINT_STYLEA(0, "FontSize", 12); //设置对象风格
+        LODOP.PRINT();
+      }, 500);
+    },
+    getUsbPrint() {
+      getUsbPrint().then((res) => {
+        if (res.code === 200) {
+          if (res.data.length) {
+            this.dataList = res.data;
+          }
+        }
+        // 获取系统打印机列表
+        this.$nextTick(() => {
+          setTimeout(() => {
+            this.getPrinterInfo();
+          }, 500);
+        });
+      });
+    },
+    setPinter(i) {
+      this.showVisible = true;
+      this.form = this.printerList[i];
+    },
+    getPrinterInfo() {
+      LODOP = getLodop();
+      let printerCount = LODOP.GET_PRINTER_COUNT();
+      let printerList = [];
+      for (let index = 0; index < printerCount; index++) {
+        printerList.push({ deviceName: LODOP.GET_PRINTER_NAME(index) });
+      }
+      this.printerList = printerList.map((v) => {
+        let obj = this.dataList.find((ele) => {
+          return ele.deviceName === v.deviceName;
+        });
+        if (obj) {
+          v = obj;
+        } else {
+          v.openOrderPrint = 0;
+          v.openOrderCancelPrint = 0;
+          v.printCustomerCount = 1;
+          v.printMerchantCount = 1;
+          v.printKitchenCount = 1;
+          v.width = 58;
+        }
+
+        return v;
+      });
+      this.SET_USBPRINTER(this.printerList)
+      console.log("数量:", printerCount);
+      console.log("打印机:", printerList);
+    },
+    save() {
+      console.log(this.form);
+      this.loading = true;
+      addUsbPrint(this.form).then((res) => {
+        if (res.code === 200) {
+          this.$message({
+            type: "success",
+            message: `修改成功!`,
+          });
+          this.showVisible = false;
+          this.getUsbPrint();
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+        this.loading = false;
+      });
+    },
+    add(type) {
+      switch (type) {
+        case 1:
+          this.form.printCustomerCount = ++this.form.printCustomerCount;
+          break;
+        case 2:
+          this.form.printMerchantCount = ++this.form.printMerchantCount;
+          break;
+        case 3:
+          this.form.printKitchenCount = ++this.form.printKitchenCount;
+          break;
+
+        default:
+          break;
+      }
+    },
+    reduce(type) {
+      switch (type) {
+        case 1:
+          this.form.printCustomerCount = this.form.printCustomerCount
+            ? --this.form.printCustomerCount
+            : this.form.printCustomerCount;
+          break;
+        case 2:
+          this.form.printMerchantCount = this.form.printMerchantCount
+            ? --this.form.printMerchantCount
+            : this.form.printMerchantCount;
+          break;
+        case 3:
+          this.form.printKitchenCount = this.form.printKitchenCount
+            ? --this.form.printKitchenCount
+            : this.form.printKitchenCount;
+          break;
+
+        default:
+          break;
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss">
+// 添加颜色类
+.el-radio__input.is-checked + .el-radio__label {
+  color: #fc7200 !important;
+}
+.el-radio__input.is-checked .el-radio__inner {
+  background: #fc7200 !important;
+  border-color: #fc7200 !important;
+}
+.shopAdd {
+  .header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin: 10px;
+    .left {
+      display: flex;
+      align-items: center;
+
+      .head-line {
+        position: relative;
+        width: 4px;
+        height: 15px;
+        background: #fc7200;
+        border-radius: 4px;
+        overflow: hidden;
+        margin-right: 10px;
+
+        .b_line {
+          width: 100px;
+          height: 6px;
+          background: #462bf7;
+        }
+
+        .triangle {
+          width: 0;
+          height: 0;
+          border-top: 100px solid #462bf7;
+          border-left: 100px solid transparent;
+        }
+      }
+
+      .label {
+        font-size: 16px;
+        font-weight: 500;
+        color: #0d1e40;
+      }
+    }
+  }
+  .printer-list {
+    display: flex;
+    flex-wrap: wrap;
+    width: calc(100% - 20px);
+    background-color: #fff;
+    padding: 10px;
+
+    .printer {
+      display: flex;
+      flex-direction: column;
+      // justify-content: center;
+      align-items: center;
+      padding: 10px;
+      width: 210px;
+      height: 140px;
+      cursor: pointer;
+      background-color: #f3f3f7;
+      margin-right: 20px;
+      .online-bg {
+        background-color: #fc7200;
+      }
+      .offline-bg {
+        background-color: #888;
+      }
+      .img-wrap {
+        display: flex;
+        flex-shrink: 0;
+        justify-content: center;
+        align-items: center;
+        width: 50px;
+        height: 50px;
+        border-radius: 50%;
+        margin-top: 30px;
+        img {
+          width: 22px;
+          height: 20px;
+        }
+      }
+      .name {
+        margin-top: 15px;
+        text-align: center;
+      }
+    }
+  }
+  .printer-num {
+    display: flex;
+    align-items: center;
+    .reduce {
+      width: 30px;
+      height: 30px;
+      cursor: pointer;
+    }
+    .num {
+      margin: 0 10px;
+    }
+    .add {
+      width: 30px;
+      height: 30px;
+      cursor: pointer;
+    }
+    .name {
+      margin-left: 20px;
+    }
+  }
+  .el-dialog {
+    border-radius: 16px;
+    overflow: hidden;
+  }
+  .print-test {
+    cursor: pointer;
+  }
+  .el-dialog__headerbtn .el-dialog__close:hover {
+    color: #909399;
+  }
+
+  .el-dialog__header {
+    /*height: 48px;*/
+    background: #f7f7f7;
+    padding: 16px 20px;
+  }
+
+  .el-dialog__title {
+    font-size: 16px;
+    font-weight: 500;
+    color: #000000;
+  }
+
+  .el-form-item__label {
+    text-align: left;
+    color: #000000;
+  }
+
+  .el-input__inner:focus {
+    border-color: #fc7b0f;
+  }
+
+  .el-input__inner {
+    color: #222222;
+  }
+
+  .line {
+    position: absolute;
+    left: -103px;
+    right: 0;
+    bottom: -12px;
+    border: 0.5px dashed #e0e0e0;
+  }
+
+  .logo_box {
+    width: 100%;
+    height: 40px;
+    display: flex;
+    align-items: center;
+    line-height: 0;
+
+    img {
+      width: 20px;
+      height: 20px;
+      border-radius: 50%;
+      margin-right: 10px;
+      vertical-align: top;
+    }
+  }
+
+  .reviewed {
+    .item {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      height: 40px;
+
+      .left {
+        display: flex;
+        align-items: center;
+        line-height: 0;
+
+        .logo {
+          width: 20px;
+          height: 20px;
+          border-radius: 50%;
+          margin-right: 10px;
+        }
+
+        .label {
+          font-size: 14px;
+          color: #000000;
+        }
+      }
+
+      .tip {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: 60px;
+        height: 22px;
+        border-radius: 22px;
+        background: #f74141;
+        font-size: 12px;
+        color: #ffffff;
+      }
+    }
+  }
+
+  .btn {
+    background: #fc7200;
+    color: #ffffff;
+    width: 220px;
+  }
+}
+</style>

+ 52 - 13
src/components/shopInfo.vue

@@ -4,7 +4,15 @@
       <el-col :span="24">
         <div class="tabList">
           <div class="tab_item" @click="changeTabs(i)" :class="{'tab_item_ac':tabNum==i?true:false}" v-for="(item,i) in tabList" :key="i">
-            <span>{{item.name}}</span>
+            <span class="item" v-if="!item.children">{{item.name}}</span>
+            <el-dropdown v-else @command="choosePrint">
+              <span class="el-dropdown-link item">
+                {{item.name}}<i class="el-icon-arrow-down el-icon--right"></i>
+              </span>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item :command="v.command" v-for="(v,index) in item.children" :key="index">{{v.name}}</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
             <div class="tab_line"></div>
           </div>
         </div>
@@ -17,7 +25,6 @@
       </el-col>
     </el-row>
     <merchant-add ref="merchantAdd" :products="productList"></merchant-add>
-
   </div>
 </template>
 
@@ -27,6 +34,7 @@ import shopList from "./shopCompoents/shopList";
 import storeList from "./shopCompoents/bindTakeOut.vue";
 import deliveryList from "./shopCompoents/bindDelivery.vue";
 import printerList from "./shopCompoents/bindPrinter.vue";
+import usbPrinter from "./shopCompoents/bindUsbPrint.vue";
 import bus from "../common/bus.js";
 import { getProductList } from "../api/shop.js";
 export default {
@@ -37,16 +45,24 @@ export default {
     storeList,
     deliveryList,
     printerList,
+    usbPrinter,
   },
 
   data() {
     return {
       activeName: "shopList",
       tabList: [
-        { name: "门店列表", index: 0, activeName: "shopList" },
-        { name: "绑定外卖平台", index: 1, activeName: "storeList" },
-        { name: "绑定配送平台", index: 2, activeName: "deliveryList" },
-        { name: "绑定打印机", index: 3, activeName: "printerList" },
+        { name: "门店列表", activeName: "shopList" },
+        { name: "绑定外卖平台", activeName: "storeList" },
+        { name: "绑定配送平台", activeName: "deliveryList" },
+        {
+          name: "绑定打印机",
+          activeName: "printerList",
+          children: [
+            { name: "云打印机", command: "printerList" },
+            { name: "USB打印机", command: "usbPrinter" },
+          ],
+        },
       ],
       tabNum: 0,
       renderComponent: true,
@@ -83,6 +99,28 @@ export default {
   },
   mounted() {},
   methods: {
+    choosePrint(e) {
+      console.log("object", e);
+      if (this.memberType === 1) {
+        this.$confirm("您当前还不是商户,请先申请成为商户!", "提示", {
+          confirmButtonText: "成为商户",
+          cancelButtonText: "取消",
+          type: "warning",
+          center: true,
+        })
+          .then(() => {
+            this.$refs.merchantAdd.init(0);
+          })
+          .catch(() => {});
+      }
+      if (this.tabNum === 3) {
+        this.activeName = e;
+        this.forceRerender();
+        return;
+      }
+      this.tabNum = 3;
+      this.activeName = e;
+    },
     forceRerender() {
       // 从 DOM 中删除 my-component 组件
       this.renderComponent = false;
@@ -146,13 +184,14 @@ export default {
       .tab_item {
         min-width: 58px;
         margin-right: 56px;
-        font-size: 16px;
-        font-weight: 500;
-        color: #b1b1b1;
-        position: relative;
-        text-align: center;
-        cursor: pointer;
-
+        .item {
+          font-size: 16px;
+          font-weight: 500;
+          color: #b1b1b1;
+          position: relative;
+          text-align: center;
+          cursor: pointer;
+        }
         .tab_line {
           width: 58px;
           height: 6px;

+ 2 - 8
src/main.js

@@ -3,23 +3,17 @@
 import Vue from 'vue'
 import App from './App'
 import router from './router'
-
 import Elementui from 'element-ui'
 import 'element-ui/lib/theme-chalk/index.css';
 import store from './store/index.js';
-
 import axios from 'axios'
-Vue.prototype.$axios = axios    //全局注册,使用方法为:this.$axios
-
 import AmapVue from '@amap/amap-vue';
-
 import { get, post, postJson } from './api/http'
-
 import Tool from './api/tool'
-Vue.prototype.$tool = Tool;
 
+Vue.prototype.$axios = axios    //全局注册,使用方法为:this.$axios
+Vue.prototype.$tool = Tool;
 Vue.config.productionTip = false
-
 Vue.prototype.$get = get;
 Vue.prototype.$post = post;
 Vue.prototype.$postJson = postJson;

+ 56 - 4
src/store/index.js

@@ -1,17 +1,60 @@
 import Vue from 'vue';
 import Vuex from 'vuex';
 import { getConfig } from '../api/setting.js';
+import { getUsbPrint } from '../api/shop.js';
+import { getLodop } from "../common/LodopFuncs.js";
+
 Vue.use(Vuex);
 
 const state = {
-  userInfo: null || JSON.parse(localStorage.getItem('userInfo'))
+  userInfo: null || JSON.parse(localStorage.getItem('userInfo')),
+  usbPrinter: [] || JSON.parse(localStorage.getItem('usbPrinter'))
 }
 
 const actions = {
   getUserInfo(context) {
     getConfig().then(res => {
       if (res.code === 200) {
-        context.commit('SET_USERINFO', res.data)
+        context.commit('SET_USERINFO', data)
+      } else {
+        this.$message({
+          type: 'error',
+          message: res.msg
+        })
+      }
+    })
+  },
+  getUsbPrint(context) {
+    getUsbPrint().then(res => {
+      if (res.code === 200) {
+        let dataList = res.data
+        if (!dataList.length) { return }
+        setTimeout(() => {
+          LODOP = getLodop();
+          let printerCount = LODOP.GET_PRINTER_COUNT();
+          if (!printerCount) { return }
+          let printerList = [];
+          for (let index = 0; index < printerCount; index++) {
+            printerList.push({ deviceName: LODOP.GET_PRINTER_NAME(index) });
+          }
+          let data = printerList.map((v) => {
+            let obj = dataList.find((ele) => {
+              return ele.deviceName === v.deviceName;
+            });
+            if (obj) {
+              v = obj;
+            } else {
+              v.openOrderPrint = 0;
+              v.openOrderCancelPrint = 0;
+              v.printCustomerCount = 1;
+              v.printMerchantCount = 1;
+              v.printKitchenCount = 1;
+              v.width = 58;
+            }
+            return v;
+          });
+          context.commit('SET_USBPRINTER', data)
+        }, 500);
       } else {
         this.$message({
           type: 'error',
@@ -24,17 +67,26 @@ const actions = {
 
 const mutations = {
   SET_USERINFO: (state, userInfo) => {
-    console.log('进来了', userInfo);
     state.userInfo = userInfo;
     // 防止页面刷新,导致Vuex重启
     localStorage.setItem('userInfo', JSON.stringify(userInfo));
+  },
+  SET_USBPRINTER: (state, usbPrinter) => {
+    state.usbPrinter = usbPrinter.filter(v => {
+      return v.status
+    });
+    // 防止页面刷新,导致Vuex重启
+    localStorage.setItem('usbPrinter', JSON.stringify(state.usbPrinter));
   }
 }
 
 const getters = {
   userInfo: (state) => {
     return state.userInfo
-  }
+  },
+  usbPrinter: (state) => {
+    return state.usbPrinter
+  },
 }
 
 const store = new Vuex.Store({

+ 1 - 0
src/views/login.vue

@@ -120,6 +120,7 @@ export default {
           this.errCount = 0;
           localStorage.setItem("token", res.data.token);
           this.SET_USERINFO(res.data.member);
+          this.$store.dispatch("getUsbPrint");
           this.$router.push("/");
         } else {
           this.$message({

BIN
static/image/usb-offline.png


BIN
static/image/usb-online.png


+ 8 - 2
vue.config.js

@@ -3,7 +3,7 @@ const path = require('path')
 module.exports = {
   publicPath: "/",
   outputDir: "dist",
-  assetsDir:"static",
+  assetsDir: "static",
   lintOnSave: false, // 关闭eslint
   runtimeCompiler: true,
   chainWebpack: config => {
@@ -25,6 +25,12 @@ module.exports = {
         // options placed here will be merged with default configuration and passed to electron-builder
         "productName": "liebao-web",
         "appId": "XXX",
+        "publish": [
+          {
+            "provider": "generic",
+            "url": "https://pc.liebaoai.cn/download/liebao-web%20Setup%200.1.0.exe",//更新服务器地址,可为空
+          }
+        ],
         "mac": {
           "icon": "./static/image/desk-logo.ico"
         },
@@ -34,7 +40,7 @@ module.exports = {
         "linux": {
           "icon": "./static/image/desk-logo.ico"
         },
-        "asar":false,
+        "asar": false,
         "nsis": {
           "oneClick": false,
           "guid": "猎豹AI聚合配送",