Browse Source

添加二维码打印

yangg 6 months ago
parent
commit
9452eda18b
91 changed files with 1882 additions and 237 deletions
  1. 1 1
      manager-admin/dist/index.html
  2. 0 0
      manager-admin/dist/static/js/19.e9c8a322dc62c61d7daf.js
  3. BIN
      manager-admin/dist/static/js/19.e9c8a322dc62c61d7daf.js.gz
  4. 0 0
      manager-admin/dist/static/js/20.c131a76a90f2d558c3ce.js
  5. BIN
      manager-admin/dist/static/js/20.c131a76a90f2d558c3ce.js.gz
  6. 0 0
      manager-admin/dist/static/js/21.62cd71ef5c817794a2ab.js
  7. 0 0
      manager-admin/dist/static/js/22.919b4e86e51e0c069846.js
  8. 0 0
      manager-admin/dist/static/js/22.9e2cae0dbbc0d66411fa.js
  9. 0 0
      manager-admin/dist/static/js/23.9117586625e2a116d86b.js
  10. BIN
      manager-admin/dist/static/js/23.9117586625e2a116d86b.js.gz
  11. 0 0
      manager-admin/dist/static/js/24.afcc7a4069cfd149c66c.js
  12. BIN
      manager-admin/dist/static/js/25.92af13fcbf4b2ab80176.js.gz
  13. 0 0
      manager-admin/dist/static/js/25.ede0939db2500b73400a.js
  14. 0 0
      manager-admin/dist/static/js/26.3edebe2a1210fd941e95.js
  15. BIN
      manager-admin/dist/static/js/26.3edebe2a1210fd941e95.js.gz
  16. BIN
      manager-admin/dist/static/js/26.652c7bf604edec883283.js.gz
  17. 0 0
      manager-admin/dist/static/js/27.2493fcbe2784d028e107.js
  18. BIN
      manager-admin/dist/static/js/27.2493fcbe2784d028e107.js.gz
  19. 0 0
      manager-admin/dist/static/js/27.91b8bf76c49226bf174d.js
  20. BIN
      manager-admin/dist/static/js/27.91b8bf76c49226bf174d.js.gz
  21. 0 0
      manager-admin/dist/static/js/36.dde7c135eb1bc0a1a4f5.js
  22. 0 0
      manager-admin/dist/static/js/36.f344dff53a11dc70891d.js
  23. BIN
      manager-admin/dist/static/js/36.f344dff53a11dc70891d.js.gz
  24. 0 0
      manager-admin/dist/static/js/37.161c8a81b2c2bca51cf1.js
  25. 0 0
      manager-admin/dist/static/js/38.fc15c95b20fb51fa43c0.js
  26. 0 0
      manager-admin/dist/static/js/39.c54c60e23a7c287493f7.js
  27. BIN
      manager-admin/dist/static/js/39.c54c60e23a7c287493f7.js.gz
  28. 0 0
      manager-admin/dist/static/js/40.1f396f6928fa20157a79.js
  29. BIN
      manager-admin/dist/static/js/40.1f396f6928fa20157a79.js.gz
  30. BIN
      manager-admin/dist/static/js/40.64f5a5b8a710eef71f8f.js.gz
  31. 0 0
      manager-admin/dist/static/js/41.0b358b3d6e093c51d194.js
  32. 0 0
      manager-admin/dist/static/js/42.aa37b232d98377dbe6f4.js
  33. 0 0
      manager-admin/dist/static/js/43.c21fd693da6a52438074.js
  34. BIN
      manager-admin/dist/static/js/43.c21fd693da6a52438074.js.gz
  35. 0 0
      manager-admin/dist/static/js/44.ca6f24b90a3f62093c21.js
  36. BIN
      manager-admin/dist/static/js/44.ca6f24b90a3f62093c21.js.gz
  37. 0 0
      manager-admin/dist/static/js/44.d63bb7dcb2c586fe9a6a.js
  38. BIN
      manager-admin/dist/static/js/44.d63bb7dcb2c586fe9a6a.js.gz
  39. 0 0
      manager-admin/dist/static/js/45.b99401ba01070605fa25.js
  40. BIN
      manager-admin/dist/static/js/45.e0c735ab8c8de19f8130.js.gz
  41. 0 0
      manager-admin/dist/static/js/46.08c7ad2a0c13483ca5c7.js
  42. BIN
      manager-admin/dist/static/js/46.08c7ad2a0c13483ca5c7.js.gz
  43. 0 0
      manager-admin/dist/static/js/47.09202cdcb13c414bbc3c.js
  44. BIN
      manager-admin/dist/static/js/47.09202cdcb13c414bbc3c.js.gz
  45. 0 0
      manager-admin/dist/static/js/49.b6f3d19b8d56901c3a22.js
  46. BIN
      manager-admin/dist/static/js/49.b6f3d19b8d56901c3a22.js.gz
  47. 0 0
      manager-admin/dist/static/js/49.e9505077a244dba35eb5.js
  48. BIN
      manager-admin/dist/static/js/49.e9505077a244dba35eb5.js.gz
  49. BIN
      manager-admin/dist/static/js/50.989cccb5090e7b376805.js.gz
  50. 0 0
      manager-admin/dist/static/js/50.f983ee244d4883652f99.js
  51. BIN
      manager-admin/dist/static/js/50.f983ee244d4883652f99.js.gz
  52. 0 0
      manager-admin/dist/static/js/51.26f49e313e6c02f45cdc.js
  53. BIN
      manager-admin/dist/static/js/51.26f49e313e6c02f45cdc.js.gz
  54. BIN
      manager-admin/dist/static/js/52.0ac647d7489770a2289e.js.gz
  55. 0 0
      manager-admin/dist/static/js/52.8843386861f6b6ce6317.js
  56. 0 0
      manager-admin/dist/static/js/53.380f75486041c152e80b.js
  57. 0 0
      manager-admin/dist/static/js/53.a1ec69e7f1a929a358ec.js
  58. BIN
      manager-admin/dist/static/js/53.a1ec69e7f1a929a358ec.js.gz
  59. 0 0
      manager-admin/dist/static/js/54.8924b4006017c9f236be.js
  60. 0 0
      manager-admin/dist/static/js/55.b10059876849f3510bcc.js
  61. 0 0
      manager-admin/dist/static/js/56.3bd7540cec0658ecd964.js
  62. 0 0
      manager-admin/dist/static/js/57.50e4084592e79fe1e5c3.js
  63. 0 0
      manager-admin/dist/static/js/58.5383c0102930721699da.js
  64. BIN
      manager-admin/dist/static/js/58.5383c0102930721699da.js.gz
  65. 0 0
      manager-admin/dist/static/js/59.084f5da2c4e8e01a44a1.js
  66. BIN
      manager-admin/dist/static/js/60.783ca013834bc61fd552.js.gz
  67. 0 0
      manager-admin/dist/static/js/60.a7277e1dec5d21a52561.js
  68. 0 0
      manager-admin/dist/static/js/61.61b4ab29d9f962919eb0.js
  69. BIN
      manager-admin/dist/static/js/61.61b4ab29d9f962919eb0.js.gz
  70. 0 0
      manager-admin/dist/static/js/62.8a15e8641a108a020488.js
  71. BIN
      manager-admin/dist/static/js/62.8a15e8641a108a020488.js.gz
  72. 0 0
      manager-admin/dist/static/js/63.85af4c9ff364445c7987.js
  73. BIN
      manager-admin/dist/static/js/63.85af4c9ff364445c7987.js.gz
  74. BIN
      manager-admin/dist/static/js/63.f646ac243834fafed6ed.js.gz
  75. BIN
      manager-admin/dist/static/js/app.439e4002aa7567919bfb.js.gz
  76. 0 0
      manager-admin/dist/static/js/app.898fa563ba7da5be5c6d.js
  77. BIN
      manager-admin/dist/static/js/app.898fa563ba7da5be5c6d.js.gz
  78. 0 0
      manager-admin/dist/static/js/manifest.b4f9ab7421595874c817.js
  79. 0 0
      manager-admin/dist/static/js/manifest.f33ac775632c8bdbfd5c.js
  80. 3 0
      manager-admin/src/main.js
  81. 4 4
      manager-admin/src/views/basicSetting/goods/index.vue
  82. 718 112
      manager-admin/src/views/basicSetting/skuSort.vue
  83. 724 38
      manager-admin/src/views/setting/serialList.vue
  84. 168 63
      manager-admin/src/views/stock/goodsExchange/goodsExchange.vue
  85. 2 2
      manager-admin/src/views/stock/order.vue
  86. 2 2
      manager-admin/src/views/stock/sendOrder.vue
  87. 0 10
      node_modules/.yarn-integrity
  88. 165 1
      package-lock.json
  89. 3 1
      package.json
  90. 3 3
      ui-domain/api.js
  91. 89 0
      yarn.lock

+ 1 - 1
manager-admin/dist/index.html

@@ -1,3 +1,3 @@
 <!DOCTYPE html><html><head><meta charset=utf-8><script>var ua = window.navigator.userAgent
     var isIe = /MSIE|Trident/.test(ua)
-    // if (isIe) window.location.href = 'http://support.dmeng.net/upgrade-your-browser.html?referrer=' + encodeURIComponent(window.location.href)</script><script src=/static/js/envs.js></script><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>erp</title><link rel="shortcut icon" href=/favicon.ico><link href=/static/css/app.2504f4a014a0e06a9efabe33f1571f70.css rel=stylesheet></head><body><div id=app><div style="display: flex;width: 100vw;height: 100vh;justify-content:center;align-items:center"><img src=/static/img/index.ripple-radio-preloader.gif alt=""></div></div><script src=/static/js/jquery.min.js></script><script src=/static/js/xlsx.full.min.js></script><script src=/static/js/echarts.min.js></script><script src=/static/js/base64.min.js></script><script src=/static/js/psl.min.js></script><script src=/static/UE/ueditor.config.js></script><script src=/static/UE/ueditor.all.js></script><script src=/static/UE/lang/zh-cn/zh-cn.js></script><script src=/static/UE/ueditor.parse.js></script><script src="//webapi.amap.com/maps?v=2.0&key=a4553619077791eb0a6df2f450b9a03b&plugin=AMap.CircleEditor"></script><script src=//webapi.amap.com/ui/1.1/main.js></script><script type=text/javascript src=/static/js/manifest.b4f9ab7421595874c817.js></script><script type=text/javascript src=/static/js/vendor.4b8436f4db68c4fe04db.js></script><script type=text/javascript src=/static/js/app.439e4002aa7567919bfb.js></script></body></html>
+    // if (isIe) window.location.href = 'http://support.dmeng.net/upgrade-your-browser.html?referrer=' + encodeURIComponent(window.location.href)</script><script src=/static/js/envs.js></script><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>erp</title><link rel="shortcut icon" href=/favicon.ico><link href=/static/css/app.2504f4a014a0e06a9efabe33f1571f70.css rel=stylesheet></head><body><div id=app><div style="display: flex;width: 100vw;height: 100vh;justify-content:center;align-items:center"><img src=/static/img/index.ripple-radio-preloader.gif alt=""></div></div><script src=/static/js/jquery.min.js></script><script src=/static/js/xlsx.full.min.js></script><script src=/static/js/echarts.min.js></script><script src=/static/js/base64.min.js></script><script src=/static/js/psl.min.js></script><script src=/static/UE/ueditor.config.js></script><script src=/static/UE/ueditor.all.js></script><script src=/static/UE/lang/zh-cn/zh-cn.js></script><script src=/static/UE/ueditor.parse.js></script><script src="//webapi.amap.com/maps?v=2.0&key=a4553619077791eb0a6df2f450b9a03b&plugin=AMap.CircleEditor"></script><script src=//webapi.amap.com/ui/1.1/main.js></script><script type=text/javascript src=/static/js/manifest.f33ac775632c8bdbfd5c.js></script><script type=text/javascript src=/static/js/vendor.4b8436f4db68c4fe04db.js></script><script type=text/javascript src=/static/js/app.898fa563ba7da5be5c6d.js></script></body></html>

File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/19.e9c8a322dc62c61d7daf.js


BIN
manager-admin/dist/static/js/19.e9c8a322dc62c61d7daf.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/20.c131a76a90f2d558c3ce.js


BIN
manager-admin/dist/static/js/19.b80a80773ec4477f7b64.js.gz → manager-admin/dist/static/js/20.c131a76a90f2d558c3ce.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/21.62cd71ef5c817794a2ab.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/22.919b4e86e51e0c069846.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/22.9e2cae0dbbc0d66411fa.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/23.9117586625e2a116d86b.js


BIN
manager-admin/dist/static/js/23.9117586625e2a116d86b.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/24.afcc7a4069cfd149c66c.js


BIN
manager-admin/dist/static/js/25.92af13fcbf4b2ab80176.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/25.ede0939db2500b73400a.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/26.3edebe2a1210fd941e95.js


BIN
manager-admin/dist/static/js/26.3edebe2a1210fd941e95.js.gz


BIN
manager-admin/dist/static/js/26.652c7bf604edec883283.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/27.2493fcbe2784d028e107.js


BIN
manager-admin/dist/static/js/27.2493fcbe2784d028e107.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/27.91b8bf76c49226bf174d.js


BIN
manager-admin/dist/static/js/27.91b8bf76c49226bf174d.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/36.dde7c135eb1bc0a1a4f5.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/36.f344dff53a11dc70891d.js


BIN
manager-admin/dist/static/js/36.f344dff53a11dc70891d.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/37.161c8a81b2c2bca51cf1.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/38.fc15c95b20fb51fa43c0.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/39.c54c60e23a7c287493f7.js


BIN
manager-admin/dist/static/js/39.c54c60e23a7c287493f7.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/40.1f396f6928fa20157a79.js


BIN
manager-admin/dist/static/js/41.105519940ff667762160.js.gz → manager-admin/dist/static/js/40.1f396f6928fa20157a79.js.gz


BIN
manager-admin/dist/static/js/40.64f5a5b8a710eef71f8f.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/41.0b358b3d6e093c51d194.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/42.aa37b232d98377dbe6f4.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/43.c21fd693da6a52438074.js


BIN
manager-admin/dist/static/js/43.c21fd693da6a52438074.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/44.ca6f24b90a3f62093c21.js


BIN
manager-admin/dist/static/js/44.ca6f24b90a3f62093c21.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/44.d63bb7dcb2c586fe9a6a.js


BIN
manager-admin/dist/static/js/46.2a923d564f5bcc358812.js.gz → manager-admin/dist/static/js/44.d63bb7dcb2c586fe9a6a.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/45.b99401ba01070605fa25.js


BIN
manager-admin/dist/static/js/45.e0c735ab8c8de19f8130.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/46.08c7ad2a0c13483ca5c7.js


BIN
manager-admin/dist/static/js/46.08c7ad2a0c13483ca5c7.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/47.09202cdcb13c414bbc3c.js


BIN
manager-admin/dist/static/js/47.09202cdcb13c414bbc3c.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/49.b6f3d19b8d56901c3a22.js


BIN
manager-admin/dist/static/js/49.b6f3d19b8d56901c3a22.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/49.e9505077a244dba35eb5.js


BIN
manager-admin/dist/static/js/49.e9505077a244dba35eb5.js.gz


BIN
manager-admin/dist/static/js/50.989cccb5090e7b376805.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/50.f983ee244d4883652f99.js


BIN
manager-admin/dist/static/js/51.400bb4cb7607c0f3a438.js.gz → manager-admin/dist/static/js/50.f983ee244d4883652f99.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/51.26f49e313e6c02f45cdc.js


BIN
manager-admin/dist/static/js/51.26f49e313e6c02f45cdc.js.gz


BIN
manager-admin/dist/static/js/52.0ac647d7489770a2289e.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/52.8843386861f6b6ce6317.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/53.380f75486041c152e80b.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/53.a1ec69e7f1a929a358ec.js


BIN
manager-admin/dist/static/js/53.a1ec69e7f1a929a358ec.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/54.8924b4006017c9f236be.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/55.b10059876849f3510bcc.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/56.3bd7540cec0658ecd964.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/57.50e4084592e79fe1e5c3.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/58.5383c0102930721699da.js


BIN
manager-admin/dist/static/js/58.5383c0102930721699da.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/59.084f5da2c4e8e01a44a1.js


BIN
manager-admin/dist/static/js/60.783ca013834bc61fd552.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/60.a7277e1dec5d21a52561.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/61.61b4ab29d9f962919eb0.js


BIN
manager-admin/dist/static/js/61.61b4ab29d9f962919eb0.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/62.8a15e8641a108a020488.js


BIN
manager-admin/dist/static/js/62.8a15e8641a108a020488.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/63.85af4c9ff364445c7987.js


BIN
manager-admin/dist/static/js/63.85af4c9ff364445c7987.js.gz


BIN
manager-admin/dist/static/js/63.f646ac243834fafed6ed.js.gz


BIN
manager-admin/dist/static/js/app.439e4002aa7567919bfb.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/app.898fa563ba7da5be5c6d.js


BIN
manager-admin/dist/static/js/app.898fa563ba7da5be5c6d.js.gz


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/manifest.b4f9ab7421595874c817.js


File diff suppressed because it is too large
+ 0 - 0
manager-admin/dist/static/js/manifest.f33ac775632c8bdbfd5c.js


+ 3 - 0
manager-admin/src/main.js

@@ -98,6 +98,9 @@ Object.keys(filters).forEach(key => {
 Vue.mixin(mixin)
 
 Vue.config.productionTip = false
+/* import Print from 'vue-print-nb'
+
+Vue.use(Print); */
 
 new Vue({
   el: '#app',

+ 4 - 4
manager-admin/src/views/basicSetting/goods/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div>
     <el-row>
-      <el-col :span="6" style="padding: 10px 0 0 10px">
+      <el-col :span="5" style="padding: 10px 0 0 10px">
         <div class="toolbar">
           <div class="inner-toolbar">
             <div class="toolbar-btns">
@@ -37,7 +37,7 @@
           </span>
         </el-tree>
       </el-col>
-      <el-col :span="18">
+      <el-col :span="19">
         <en-table-layout :tableData="tableData.data" class="draggable-table" :row-key="getRowKeys" :loading="loading"
           style="margin: 10px 10px 0 10px">
           <div slot="toolbar" class="inner-toolbar">
@@ -47,8 +47,8 @@
               <el-button size="mini" v-if="checkPermission(['goodsAddForm'])" type="primary"
                 @click="handleAddGoods('hire')">新增租赁商品</el-button>
             </div>
-            <div class="toolbar-search" style="display: flex; align-items: center;">
-              <span style=" white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">商品编号/序列号:</span>
+            <div class="toolbar-search" style="display: flex; align-items: center; min-width: 580px;">
+              <span style=" white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width: 150px;">商品编号/序列号/商品名称:</span>
               <en-table-search @search="searchEvent" placeholder="请输入关键字搜索" />
               <el-button style="margin-left: 5px;" @click="refresh" icon="el-icon-refresh" type="info" plain></el-button>
             </div>

+ 718 - 112
manager-admin/src/views/basicSetting/skuSort.vue

@@ -1,5 +1,30 @@
 <template>
   <div>
+    <div class="search-area">
+      <el-form ref="searchForm" :model="searchForm" :inline="true">
+        <el-form-item label="商品名称">
+          <el-input
+            v-model="searchForm.goods_name"
+            placeholder="请输入商品名称"
+            clearable
+            @keyup.enter.native="handleSearch"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="SKU">
+          <el-input
+            v-model="searchForm.sku"
+            placeholder="请输入SKU"
+            clearable
+            @keyup.enter.native="handleSearch"
+          ></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleSearch">搜索</el-button>
+          <el-button @click="handleReset">重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+
     <en-table-layout
       :tableData="tableData.data"
       :loading="loading"
@@ -14,6 +39,12 @@
             :disabled="multipleSelection.length === 0"
             @click="batchPrint"
             >批量打印</el-button
+          ><el-button
+            size="mini"
+            type="primary"
+            :disabled="multipleSelection.length === 0"
+            @click="qRcode"
+            >二维码打印</el-button
           >
         </div>
         <!-- <en-table-search @search="searchEvent" @advancedSearch="advancedSearchEvent" advanced advancedWidth="465"
@@ -86,9 +117,8 @@
         </el-table-column> -->
         <el-table-column label="操作" width="310">
           <template slot-scope="scope">
-            <el-button size="mini" @click="PrintIng(scope.row)"
-              >打印SKU</el-button
-            >
+            <el-button size="mini" @click="PrintIng(scope.row)">打印SKU</el-button>
+            <el-button size="mini" @click="handleSingleQRCode(scope.row)">二维码打印</el-button>
           </template>
         </el-table-column>
       </template>
@@ -117,7 +147,7 @@
         <div class="logInfo">操作时间:{{ currDetailLog.operate_time | unixToDate }}</div>
       </el-dialog> -->
     <el-dialog
-      title="打印预览"
+      title="打印设置"
       :visible.sync="PrintVisible"
       width="940px"
       center
@@ -126,7 +156,13 @@
       <el-form :inline="true" class="print-options">
         <el-form-item label="打印规格">
           <el-select v-model="selectedSize" placeholder="请选择打印规格">
-            <el-option label="大号 (9.5cm × 3.5cm)" value="large"></el-option>
+            <el-option
+              v-for="option in sizeOptions"
+              :key="option.value"
+              :label="option.label"
+              :value="option.value"
+            >
+            </el-option>
           </el-select>
         </el-form-item>
         <el-form-item label="缩放">
@@ -137,13 +173,9 @@
             :step="10"
           ></el-input-number>
         </el-form-item>
-        <el-form-item label="打印方向">
-          <el-select v-model="printOrientation" placeholder="请选择打印方向">
-            <el-option label="纵向" value="portrait"></el-option>
-            <el-option label="横向" value="landscape"></el-option>
-          </el-select>
-        </el-form-item>
       </el-form>
+
+      <!-- 预览区域 -->
       <div class="print-preview-container">
         <div id="deliverySheet" :style="{ transform: `scale(${scale / 100})` }">
           <div class="tips-t" v-for="(item, index) in codeList" :key="index">
@@ -156,11 +188,62 @@
           </div>
         </div>
       </div>
+
       <div slot="footer" class="dialog-footer">
         <el-button @click="handleCancle">取消</el-button>
         <el-button type="primary" @click="handlePrintGoodsLend">打印</el-button>
       </div>
     </el-dialog>
+
+    <!-- 添加新的二维码打印弹窗 -->
+    <el-dialog
+      title="二维码打印设置"
+      :visible.sync="qrCodeVisible"
+      width="940px"
+      center
+      @close="handleQRCodeCancel"
+    >
+      <el-form :inline="true" class="print-options">
+        <el-form-item label="打印规格">
+          <el-select v-model="qrCodeSelectedSize" placeholder="请选择打印规格">
+            <el-option
+              v-for="option in qrCodeSizeOptions"
+              :key="option.value"
+              :label="option.label"
+              :value="option.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="缩放">
+          <el-input-number
+            v-model="qrCodeScale"
+            :min="50"
+            :max="150"
+            :step="10"
+          ></el-input-number>
+        </el-form-item>
+      </el-form>
+
+      <!-- 预览区域 -->
+      <div class="print-preview-container">
+        <div id="qrCodeSheet">
+          <div class="tips-t" v-for="(item, index) in qrCodeList" :key="index">
+            <div class="content-wrapper">
+              <div class="qrcode-container">
+                <div :id="`qrcode-${index}`"></div>
+              </div>
+              <!-- <div class="numOrder">{{ String(item).toUpperCase() }}</div> -->
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="handleQRCodeCancel">取消</el-button>
+        <el-button type="primary" @click="handleQRCodePrint">打印</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
@@ -169,11 +252,101 @@ import * as API_Setting from "@/api/setting";
 import * as API_ProductClass from "@/api/productClass";
 import JsBarcode from "jsbarcode";
 import Sortable from "sortablejs";
-import Print from "print-js";
+// 首先在文件顶部正确导入 QRCode
+import QRCode from "qrcodejs2";
+/* import Print from "print-js"; */
+/* import Print from "vue-print-nb";
+import Vue from "vue";
+Vue.use(Print); */
+// 添加 ArgoxPrinter 类
+
+// 修改 ArgoxPrinter 类
+class ArgoxPrinter {
+  constructor() {
+    this.printWindow = null;
+  }
+
+  print(content, options = {}) {
+    const { width, height, marginTop, marginLeft, fontSize } = options;
+    /* margin-top: ${marginTop}mm; */
+    this.printWindow = window.open("", "_blank");
+    this.printWindow.document.write(`
+      <html>
+        <head>
+          <title>打印标签</title>
+          <style>
+            @page {
+              size: ${width}mm ${height}mm;
+              margin: 0;
+            }
+            body {
+              margin: 0;
+              -webkit-print-color-adjust: exact;
+            }
+            * {
+              border: none !important;
+              outline: none !important;
+            }
+            .print-content {
+              width: ${width}mm;
+              height: ${height}mm;
+              page-break-after: always;
+              display: flex;
+              flex-direction: column;
+              justify-content: center;
+              align-items: center;
+              box-sizing: border-box;
+              padding: 1mm;
+              margin-top: ${marginTop}mm;
+              margin-left: ${marginLeft}mm;
+            }
+            .barcode-container {
+              display: flex;
+              justify-content: center;
+              align-items: center;
+              width: 100%;
+              height: 70%;
+            }
+            .barcode-container svg {
+              max-width: 100%;
+              max-height: 100%;
+            }
+            .text {
+              font-size: ${fontSize}px;
+              margin-top: 0mm;
+            }
+            @media print {
+              * {
+                border: none !important;
+                outline: none !important;
+                -webkit-print-color-adjust: exact;
+              }
+            }
+          </style>
+        </head>
+        <body>${content}</body>
+      </html>
+    `);
+
+    this.printWindow.document.close();
+
+    // 延迟执行打印操作,确保内容加载完成
+    setTimeout(() => {
+      this.printWindow.focus();
+      this.printWindow.print();
+      // 打印完成后关闭窗口
+      setTimeout(() => {
+        this.printWindow.close();
+      }, 500);
+    }, 500);
+  }
+}
+
 export default {
   name: "systemLogs",
   data() {
     return {
+      printer: null, // 添加打印机实例
       // 列表loading状态
       loading: false,
       // 列表参数
@@ -191,23 +364,162 @@ export default {
       currDetailLog: {},
       // 高级搜索数据
       advancedForm: {},
-      PrintVisible: false,
       codeList: [],
       barcodeValue: "",
       // 当前已选择的行
       multipleSelection: [],
-      selectedSize: "large",
       scale: 100,
-      codeList: [], // 假设这里存储了需要生成条形码的
+      codeList: [], // 假设这里存储了需要生成条形码的据
       PrintVisible: false,
       printOrientation: "portrait", // 默认为纵向打印
+      // 修改 selectedSize 的初始值为 'large',确保与 sizeOptions 中的值对应
+      selectedSize: "large",
+
+      // 修改 sizeOptions 的结构,使其更清晰
+      sizeOptions: [
+        {
+          label: "45×10mm",
+          value: "medium",
+          width: 45,
+          height: 12,
+          marginTop: 0, // 添加边距配置 -0.4
+          marginLeft: 2,
+          fontSize: 7,
+        },
+        {
+          label: "50×20mm",
+          value: "large",
+          width: 50,
+          height: 20,
+          marginTop: 0, //5
+          marginLeft: 2.5,
+          fontSize: 12,
+        },
+        {
+          label: "25×10mm",
+          value: "small",
+          width: 25,
+          height: 10,
+          marginTop: 0,
+          marginLeft: 0, //-1
+          fontSize: 6,
+        },
+      ],
+      // 添加 printOptions
+      printOptions: {
+        id: "deliverySheet",
+        popTitle: "条码打印",
+        preview: false,
+        extraCss: `
+          @page {
+            size: auto;
+            margin: 0;
+          }
+          body {
+            margin: 0;
+            -webkit-print-color-adjust: exact;
+          }
+          .tips-t {
+            page-break-after: always;
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+            align-items: center;
+            box-sizing: border-box;
+            padding: 1mm;
+            /* 移除边框 */
+            border: none !important;
+            outline: none !important;
+          }
+          /* 移除所有可能的边框和轮廓 */
+          * {
+            border: none !important;
+            outline: none !important;
+          }
+          .content-wrapper {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            width: 100%;
+            height: 100%;
+          }
+          .barcode-container {
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            width: 100%;
+            height: 70%;
+          }
+          .numOrder {
+            font-size: 10px;
+            margin-top: 0.5mm;
+          }
+          /* 打印时隐藏所有边框 */
+          @media print {
+            * {
+              border: none !important;
+              outline: none !important;
+              -webkit-print-color-adjust: exact;
+            }
+            .tips-t {
+              border: none !important;
+              outline: none !important;
+            }
+          }
+        `,
+      },
+      searchForm: {
+        goods_name: "",
+        sku: "",
+      },
+
+      /* 二维码 */
+      // 添加新的数据属性
+      qrCodeVisible: false,
+      qrCodeList: [],
+      qrCodeScale: 100,
+      qrCodeSelectedSize: "large",
+      qrCodeSizeOptions: [
+        {
+          label: "45×45mm",
+          value: "medium",
+          width: 45,
+          height: 45,
+          marginTop: 0,
+          marginLeft: 0,
+          qrSize: 80,
+        },
+        {
+          label: "50×50mm",
+          value: "large",
+          width: 50,
+          height: 50,
+          marginTop: 0,
+          marginLeft: 0,
+          qrSize: 100,
+        },
+        {
+          label: "25×25mm",
+          value: "small",
+          width: 20,
+          height: 20,
+          marginTop: 0,
+          marginLeft: 0,
+          qrSize: 30,
+        },
+      ],
     };
   },
   mounted() {
     this.GET_SystemLogs();
     this.rowDrop();
   },
+  created() {
+    // 创建打印机实例
+    this.printer = new ArgoxPrinter();
+  },
   watch: {
+    // 监听打印弹窗显示状态
     PrintVisible(newVal) {
       if (newVal) {
         this.$nextTick(() => {
@@ -215,20 +527,246 @@ export default {
         });
       }
     },
+    // 监听打印规格变化
+    selectedSize: {
+      handler(newSize) {
+        this.$nextTick(() => {
+          this.generateBarcodes();
+        });
+      },
+    },
+    // 添加 watch 以更新打印尺寸
+    selectedSize: {
+      handler(newSize) {
+        const sizeStyles = {
+          large: { width: "50mm", height: "20mm" },
+          medium: { width: "45mm", height: "10mm" },
+          small: { width: "25mm", height: "10mm" },
+        };
+        const selectedSizeStyle = sizeStyles[newSize];
+
+        this.printOptions.extraCss = `
+        @page {
+          size: ${selectedSizeStyle.width} ${selectedSizeStyle.height};
+          margin: 0;
+        }
+        body {
+          margin: 0;
+          -webkit-print-color-adjust: exact;
+        }
+        * {
+          border: none !important;
+          outline: none !important;
+        }
+        .tips-t {
+          width: ${selectedSizeStyle.width};
+          height: ${selectedSizeStyle.height};
+          page-break-after: always;
+          margin-top:-15px;
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          align-items: center;
+          box-sizing: border-box;
+          padding: 1mm;
+          border: none !important;
+          outline: none !important;
+        }
+        .content-wrapper {
+          display: flex;
+          flex-direction: column;
+          align-items: center;
+          width: 100%;
+          height: 100%;
+        }
+        .barcode-container {
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          width: 100%;
+          height: 70%;
+        }
+        .barcode-container svg {
+          max-width: 100%;
+          max-height: 100%;
+        }
+        .numOrder {
+          font-size: 10px;
+          margin-top: 0.5mm;
+        }
+        @media print {
+          * {
+            border: none !important;
+            outline: none !important;
+            -webkit-print-color-adjust: exact;
+          }
+          .tips-t {
+            border: none !important;
+            outline: none !important;
+          }
+        }
+      `;
+      },
+      immediate: true,
+    },
+    qrCodeSelectedSize: {
+      handler(newSize) {
+        this.$nextTick(() => {
+          this.generateQRCodes();
+        });
+      }
+    }
   },
   methods: {
-    generateBarcodes() {
+    /* 二维码打印 */
+    qRcode() {
+      if (this.multipleSelection.length === 0) {
+        this.$message.warning("请先选择要打印的商品");
+        return;
+      }
+
+      this.qrCodeList = this.multipleSelection.map((item) => item.sku);
+      this.qrCodeVisible = true;
       this.$nextTick(() => {
-        this.codeList.forEach((item, index) => {
-          JsBarcode(`#barcode-${index}`, item, {
-            format: "CODE128",
-            width: 2,
-            height: 60,
-            displayValue: false,
+        this.generateQRCodes();
+      });
+    },
+
+    generateQRCodes() {
+      this.qrCodeList.forEach((code, index) => {
+        const element = document.getElementById(`qrcode-${index}`);
+        if (element) {
+          element.innerHTML = ""; // 清除现有内容
+          
+          // 获取选中尺寸的配置
+          const selectedSize = this.qrCodeSizeOptions.find(
+            (option) => option.value === this.qrCodeSelectedSize
+          );
+          
+          // 使用对应尺寸的 qrSize
+          new QRCode(element, {
+            text: code,
+            width: selectedSize.qrSize,
+            height: selectedSize.qrSize,
+            colorDark: "#000000",
+            colorLight: "#ffffff",
+            correctLevel: QRCode.CorrectLevel.H
           });
+        }
+      });
+    },
+    handleQRCodePrint() {
+      try {
+        const selectedOption = this.qrCodeSizeOptions.find(
+          (option) => option.value === this.qrCodeSelectedSize
+        );
+
+        const printContent = this.qrCodeList
+          .map((code, index) => {
+            const qrcodeElement = document.getElementById(`qrcode-${index}`);
+            return `
+              <div class="print-content">
+                <div class="qrcode-container">
+                  ${qrcodeElement ? qrcodeElement.outerHTML : ""}
+                </div>
+               
+              </div>
+            `;
+          })
+          .join("");
+
+        this.printer.print(printContent, {
+          width: selectedOption.width,
+          height: selectedOption.height,
+          marginTop: selectedOption.marginTop,
+          marginLeft: selectedOption.marginLeft,
+          fontSize: 12,
         });
+
+        this.$message.success("打印成功");
+        this.qrCodeVisible = false;
+      } catch (error) {
+        this.$message.error("打印失败:" + error.message);
+      }
+    },
+
+    handleQRCodeCancel() {
+      this.qrCodeVisible = false;
+      this.qrCodeList = [];
+    },
+
+    // 添加搜索方法
+    handleSearch() {
+      this.params = {
+        ...this.params,
+        name: this.searchForm.goods_name,
+        sku: this.searchForm.sku,
+        page_no: 1,
+      };
+      this.GET_SystemLogs();
+    },
+
+    // 添加重置方法
+    handleReset() {
+      this.searchForm.goods_name = "";
+      this.searchForm.sku = "";
+      this.params = {
+        page_no: 1,
+        page_size: 20,
+      };
+      this.GET_SystemLogs();
+    },
+    // 修改生成条形码的方法
+    generateBarcodes() {
+      return new Promise((resolve, reject) => {
+        try {
+          this.$nextTick(() => {
+            this.codeList.forEach((code, index) => {
+              const options = this.getBarcodeOptions();
+              const element = document.getElementById(`barcode-${index}`);
+              if (element) {
+                // 清除之前的内容
+                while (element.firstChild) {
+                  element.removeChild(element.firstChild);
+                }
+                // 生成新的条形码
+                JsBarcode(
+                  `#barcode-${index}`,
+                  code, //String().toUpperCase()
+                  options
+                );
+              }
+            });
+            resolve();
+          });
+        } catch (error) {
+          reject(error);
+        }
       });
     },
+
+    // ��改获取条码配置的方法
+    getBarcodeOptions() {
+      const sizeConfig = {
+        large: { width: 1.5, height: 40 },
+        medium: { width: 1.2, height: 20 },
+        small: { width: 1, height: 15 },
+      };
+
+      // 添加默认值处理
+      const defaultConfig = { width: 1.5, height: 40 };
+      const config = sizeConfig[this.selectedSize] || defaultConfig;
+
+      return {
+        format: "CODE128",
+        width: config.width,
+        height: config.height,
+        displayValue: false,
+        margin: 5,
+        fontSize: this.selectedSize === "small" ? 8 : 12,
+        textMargin: 2,
+      };
+    },
     /*  handlePrintGoodsLend() {
       this.generateBarcodes();
       this.$nextTick(() => {
@@ -290,85 +828,109 @@ export default {
       this.multipleSelection = val;
     },
     // 批量打印
-    batchPrint() {
-      const ids = this.multipleSelection.map((item) => item.sku);
-      this.codeList = ids;
-      this.PrintVisible = true;
+    // 修改批量打印方法
+    async batchPrint() {
+      try {
+        const ids = this.multipleSelection.map((item) => item.sku);
+        this.codeList = ids;
+        // 打开选择尺寸弹窗
+        this.PrintVisible = true;
+      } catch (error) {
+        this.$message.error("批量打印失败:" + error.message);
+      }
     },
+
     /** 打印对账详情 */
-    handlePrintGoodsLend() {
-      // 生成条形码
+    /*    handlePrintGoodsLend() {
       this.generateBarcodes();
+      const _this = this;
 
-      // 准备打印样式
-      const style = `
-    @page {
-      size: ${this.printOrientation};
-      margin: 0;
-    }
-    body {
-      margin: 0;
-    }
-    .tips-t {
-      width: 95mm;
-      height: 35mm;
-      page-break-after: always;
-      display: flex;
-      flex-direction: column;
-      justify-content: center;
-      align-items: center;
-      box-sizing: border-box;
-      padding: 2mm;
-    }
-    .content-wrapper {
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-    }
-    .barcode-container {
-      margin-bottom: 2mm;
-    }
-    .numOrder {
-      font-size: 14px;
-    }
-    ${
-      this.printOrientation !== "landscape"
-        ? `
-      .tips-t {
-        transform: rotate(90deg);
-        transform-origin: top left;
-        width: 35mm;
-        height: 95mm;
-        position: absolute;
-        left: 35mm;
-        top: 0;
-      }
-    `
-        : ""
-    }
-  `;
-
-      // 使用 print-js 打印
-      Print({
-        printable: "deliverySheet",
-        type: "html",
-        css: style,
-        style: style,
-        scanStyles: false,
-        targetStyles: ["*"],
+      // 更新回调函数
+      this.printOptions.beforeOpenCallback = function () {
+        console.log("打印窗口即将打开");
+      };
+      this.printOptions.openCallback = function () {
+        console.log("打印窗口已打开");
+      };
+      this.printOptions.closeCallback = function () {
+        _this.handleCancle();
+        console.log("打印窗口已关闭");
+      };
+
+      // 触发打印
+      this.$nextTick(() => {
+        const printElement = document.getElementById("deliverySheet");
+        if (printElement) {
+          const event = new Event("click");
+          printElement.dispatchEvent(event);
+        }
       });
+    }, */
+    // 修改 handlePrintGoodsLend 方法
+    async handlePrintGoodsLend() {
+      try {
+        if (!this.selectedSize) {
+          this.$message.warning("请先选择打印尺寸");
+          return;
+        }
+
+        const selectedOption = this.sizeOptions.find(
+          (option) => option.value === this.selectedSize
+        );
+        if (!selectedOption) {
+          throw new Error("无效的打印尺寸");
+        }
+
+        await this.generateBarcodes();
+
+        const printContent = this.codeList
+          .map((code, index) => {
+            const barcodeElement = document.getElementById(`barcode-${index}`);
+            if (!barcodeElement) {
+              throw new Error("条形码生成失败");
+            }
+            return `
+          <div class="print-content">
+            <div class="barcode-container">
+              ${barcodeElement.outerHTML}
+            </div>
+            <div class="text">${String(code).toUpperCase()}</div>
+          </div>
+        `;
+          })
+          .join("");
+
+        // 使用 ArgoxPrinter 执行打印,传入所有尺寸相关的配置
+        this.printer.print(printContent, {
+          width: selectedOption.width,
+          height: selectedOption.height,
+          marginTop: selectedOption.marginTop,
+          marginLeft: selectedOption.marginLeft,
+          fontSize: selectedOption.fontSize,
+        });
+
+        this.$message.success("打印成功");
+        this.PrintVisible = false;
+      } catch (error) {
+        this.$message.error("打印失败:" + error.message);
+      }
     },
+
     handleCancle() {
       this.PrintVisible = false;
       this.codeList = [];
     },
-    // 打印
-    PrintIng(row) {
-      this.barcodeValue = row.sku;
-      this.$nextTick(() => {
-        this.codeList.push(row.sku);
+
+    // 修改单个打印方法
+    async PrintIng(row) {
+      try {
+        this.barcodeValue = row.sku;
+        this.codeList = [row.sku];
+        // 打开选择尺寸弹窗
         this.PrintVisible = true;
-      });
+      } catch (error) {
+        this.$message.error("打印失败:" + error.message);
+      }
     },
     // 行拖拽
     rowDrop() {
@@ -491,6 +1053,14 @@ export default {
       this.showLogDetail = true;
       this.currDetailLog = row;
     },
+    /** 单个二维码打印 */
+    handleSingleQRCode(row) {
+      this.qrCodeList = [row.sku];
+      this.qrCodeVisible = true;
+      this.$nextTick(() => {
+        this.generateQRCodes();
+      });
+    },
   },
 };
 </script>
@@ -567,33 +1137,63 @@ export default {
   display: flex;
   justify-content: center;
   align-items: flex-start;
+}
 
-  &.portrait {
-    #deliverySheet {
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-    }
+#deliverySheet {
+  transform-origin: top left;
+  padding: 10mm;
+}
 
-    .tips-t {
-      width: 95mm;
-      height: 35mm;
-    }
+.tips-t {
+  margin-bottom: 2mm;
+  padding: 2mm;
+  box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+
+  .content-wrapper {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
   }
 
-  &.landscape {
-    #deliverySheet {
-      display: flex;
-      flex-wrap: wrap;
-      justify-content: flex-start;
-    }
+  .barcode-container {
+    width: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
 
-    .tips-t {
-      width: 35mm;
-      height: 95mm;
-      margin-right: 2mm;
+    svg {
+      max-width: 100%;
+      max-height: 100%;
     }
   }
+
+  .numOrder {
+    margin-top: 1mm;
+    font-size: v-bind('selectedSize === "small" ? "8px" : "12px"');
+  }
+}
+
+// 根据不同尺寸设置预览大小
+.tips-t {
+  &[data-size="large"] {
+    width: 50mm;
+    height: 20mm;
+  }
+  &[data-size="medium"] {
+    width: 45mm;
+    height: 10mm;
+  }
+  &[data-size="small"] {
+    width: 25mm;
+    height: 10mm;
+  }
 }
 
 #deliverySheet {
@@ -626,15 +1226,21 @@ export default {
 
   .barcode-container {
     width: 100%;
+    height: v-bind('selectedSize === "small" ? "60%" : "70%"');
     display: flex;
     justify-content: center;
-    margin-bottom: 2mm;
+    align-items: center;
 
     svg {
       max-width: 100%;
-      height: auto;
+      max-height: 100%;
     }
   }
+
+  .numOrder {
+    font-size: v-bind('selectedSize === "small" ? "8px" : "14px"');
+    margin-top: 1mm;
+  }
 }
 #deliverySheet {
   transform-origin: top left;

+ 724 - 38
manager-admin/src/views/setting/serialList.vue

@@ -3,7 +3,7 @@
     <div class="search">
       <el-form ref="advancedForm" :model="advancedForm" label-width="160px">
         <el-row>
-          <el-col :span="12">
+          <el-col :span="7">
             <el-form-item label="sku">
               <el-input
                 v-model="advancedForm.sku"
@@ -12,7 +12,16 @@
               ></el-input>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
+          <el-col :span="6">
+            <el-form-item label="商品名称">
+              <el-input
+                v-model="advancedForm.goods_name"
+                placeholder="请输入商品名称"
+                clearable
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
             <el-form-item label="状态">
               <el-select v-model="advancedForm.status" clearable>
                 <el-option
@@ -64,6 +73,12 @@
             @click="batchPrint"
             >批量打印</el-button
           >
+          <el-button
+            size="mini"
+            type="primary"
+            :disabled="multipleSelection.length === 0"
+            @click="qRcode"
+            >二维码打印</el-button>
         </div>
         <!--
         <div class="toolbar-search" style="display: flex; align-items: center">
@@ -121,6 +136,8 @@
             <el-button size="mini" @click="PrintIng(scope.row)"
               >打印序列号</el-button
             >
+            <el-button style="margin-top: 10px;" size="mini" @click="handleSingleQRCode(scope.row)"
+              >二维码打印</el-button>
           </template>
         </el-table-column>
       </template>
@@ -141,17 +158,42 @@
     <el-dialog
       :title="title"
       :visible.sync="dialogVisible"
-      width="600px"
       @open="handleDialogOpen"
       :modal-append-to-body="false"
       :close-on-click-modal="false"
       :close-on-press-escape="false"
+      width="60%"
       @close="close"
     >
       <div class="header">
-        <span>商品编号/sku</span>
-        <el-input v-model="stockForm.sn"></el-input>
-        <el-button>搜索</el-button>
+        <!-- Replace the original search input with a form -->
+        <el-form :inline="true" :model="searchForm">
+          <!-- <el-form-item label="商品编号">
+            <el-input
+              v-model="searchForm.sn"
+              placeholder="请输入商品编号"
+              clearable
+            ></el-input>
+          </el-form-item> -->
+          <el-form-item label="SKU">
+            <el-input
+              v-model="searchForm.sku"
+              placeholder="请输入SKU"
+              clearable
+            ></el-input>
+          </el-form-item>
+          <el-form-item label="商品名称">
+            <el-input
+              v-model="searchForm.goods_name"
+              placeholder="请输入商品名称"
+              clearable
+            ></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" @click="searchAdd">搜索</el-button>
+            <el-button @click="resetSearch">重置</el-button>
+          </el-form-item>
+        </el-form>
       </div>
       <div class="center">
         <el-table
@@ -228,30 +270,43 @@
       center
       @close="handleCancle"
     >
-      <el-button
-        size="mini"
-        type="primary"
-        @click="handlePrintGoodsLend"
-        class="print"
-        >打印</el-button
-      >
-      <div id="deliverySheet" style="width: 900px">
-        <div class="tips-t" v-for="(item, index) in codeList" :key="index">
-          <div class="barcode-container">
-            <div class="barcode-wrapper">
-              <barcode
-              :displayValue="false"
-                :value="item"
-                format="CODE128"
-                textAlign="center"
-                height="65"
-                width="1"
-              ></barcode>
+      <el-form :inline="true" class="print-options">
+        <el-form-item label="打印规格">
+          <el-select v-model="selectedSize" placeholder="请选择打印规格">
+            <el-option
+              v-for="option in sizeOptions"
+              :key="option.value"
+              :label="option.label"
+              :value="option.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="缩放">
+          <el-input-number
+            v-model="scale"
+            :min="50"
+            :max="150"
+            :step="10"
+          ></el-input-number>
+        </el-form-item>
+      </el-form>
+      <div ref="printArea" class="print-preview-container">
+        <div id="deliverySheet" :style="{ transform: `scale(${scale / 100})` }">
+          <div class="tips-t" v-for="(item, index) in codeList" :key="index">
+            <div class="content-wrapper">
+              <div class="barcode-container">
+                <svg :id="`barcode-${index}`"></svg>
+              </div>
+              <div class="numOrder">{{ String(item).toUpperCase() }}</div>
             </div>
-            <div class="barcode-text">{{ item }}</div>
           </div>
         </div>
       </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="handleCancle">取消</el-button>
+        <el-button type="primary" @click="handlePrintGoodsLend">打印</el-button>
+      </div>
     </el-dialog>
     <el-dialog
       title="修改序列号"
@@ -281,6 +336,52 @@
         <el-button @click="snCodeEdit">修改</el-button>
       </span>
     </el-dialog>
+    <el-dialog
+      title="二维码打印设置"
+      :visible.sync="qrCodeVisible"
+      width="940px"
+      center
+      @close="handleQRCodeCancel"
+    >
+      <el-form :inline="true" class="print-options">
+        <el-form-item label="打印规格">
+          <el-select v-model="qrCodeSelectedSize" placeholder="请选择打印规格">
+            <el-option
+              v-for="option in qrCodeSizeOptions"
+              :key="option.value"
+              :label="option.label"
+              :value="option.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="缩放">
+          <el-input-number
+            v-model="qrCodeScale"
+            :min="50"
+            :max="150"
+            :step="10"
+          ></el-input-number>
+        </el-form-item>
+      </el-form>
+
+      <div class="print-preview-container">
+        <div id="qrCodeSheet">
+          <div class="tips-t" v-for="(item, index) in qrCodeList" :key="index">
+            <div class="content-wrapper">
+              <div class="qrcode-container">
+                <div :id="`qrcode-${index}`"></div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="handleQRCodeCancel">取消</el-button>
+        <el-button type="primary" @click="handleQRCodePrint">打印</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
@@ -290,7 +391,84 @@ import * as API_Setting from "@/api/setting";
 import * as API_Auth from "@/api/auth";
 import { Foundation } from "~/ui-utils";
 import { mapGetters } from "vuex";
-import Print from "print-js";
+import JsBarcode from "jsbarcode";
+import QRCode from "qrcodejs2";
+/* import Print from "print-js"; */
+/* import Print from "vue-print-nb";
+import Vue from "vue";
+Vue.use(Print); */
+// 添加打印机类
+class ArgoxPrinter {
+  constructor() {
+    this.printWindow = null;
+  }
+
+  print(content, options = {}) {
+    const { width, height, marginTop, marginLeft, fontSize } = options;
+
+    this.printWindow = window.open("", "_blank");
+    this.printWindow.document.write(`
+      <html>
+        <head>
+          <title>打印标签</title>
+          <style>
+            @page {
+              size: ${width}mm ${height}mm;
+              margin: 0;
+            }
+            body {
+              margin: 0;
+              -webkit-print-color-adjust: exact;
+            }
+            * {
+              border: none !important;
+              outline: none !important;
+            }
+            .print-content {
+             width: ${width}mm;
+              height: ${height}mm;
+              page-break-after: always;
+              display: flex;
+              flex-direction: column;
+              justify-content: center;
+              align-items: center;
+              box-sizing: border-box;
+              padding: 1mm;
+              margin-top: ${marginTop}mm;
+              margin-left: ${marginLeft}mm;
+            }
+            .barcode-container {
+              display: flex;
+              justify-content: center;
+              align-items: center;
+              width: 100%;
+              height: 70%;
+            }
+            .barcode-container svg {
+              max-width: 100%;
+              max-height: 100%;
+            }
+            .text {
+              font-size: ${fontSize}px;
+              margin-top: 0mm;
+            }
+          </style>
+        </head>
+        <body>${content}</body>
+      </html>
+    `);
+
+    this.printWindow.document.close();
+    setTimeout(() => {
+      this.printWindow.focus();
+      this.printWindow.print();
+      setTimeout(() => {
+        this.printWindow.close();
+      }, 500);
+    }, 500);
+  }
+}
+
 export default {
   name: "warehouse",
   data() {
@@ -315,7 +493,7 @@ export default {
       stockRules: {
         sn: [{ required: true, message: "请输入仓库编号", trigger: "blur" }],
         name: [
-          { required: true, message: "请选择入仓库名称", trigger: "blur" },
+          { required: true, message: "请选择入仓库名称", trigger: "blur" },
         ],
       },
       // 仓库表单 dialog
@@ -330,7 +508,11 @@ export default {
       title: "",
       statusList: [],
       // 高级搜索数据
-      advancedForm: {},
+      advancedForm: {
+        sku: "",
+        goods_name: "", // Add goods_name to advancedForm
+        status: "",
+      },
       barcodeValue: "",
       SKUForm: {
         snCode: "",
@@ -346,27 +528,247 @@ export default {
         ],
       },
       SKUVisible: false,
-      warehouseList: "",
+      warehouseList: [],
+      scale: 100,
+      printOrientation: "portrait",
+      printer: null,
+      selectedSize: "large",
+      sizeOptions: [
+        {
+          label: "45×10mm",
+          value: "medium",
+          width: 45,
+          height: 12,
+          marginTop:0,
+          marginLeft: 2,
+          fontSize: 6,
+        },
+        {
+          label: "50×20mm",
+          value: "large",
+          width: 50,
+          height: 20,
+          marginTop: 0,
+          marginLeft: 2.5,
+          fontSize: 12,
+        },
+        {
+          label: "25×10mm",
+          value: "small",
+          width: 25,
+          height: 10,
+          marginTop: 0,
+          marginLeft: -1,
+          fontSize: 6,
+        },
+      ],
+      searchForm: {
+        sn: "",
+        sku: "",
+        goods_name: "",
+      },
+      // 添加二维码相关数据
+      qrCodeVisible: false,
+      qrCodeList: [],
+      qrCodeScale: 100,
+      qrCodeSelectedSize: "large",
+      qrCodeSizeOptions: [
+        {
+          label: "45×45mm",
+          value: "medium",
+          width: 45,
+          height: 45,
+          marginTop: 0,
+          marginLeft: 0,
+          qrSize: 80,
+        },
+        {
+          label: "50×50mm",
+          value: "large",
+          width: 50,
+          height: 50,
+          marginTop: 0,
+          marginLeft: 0,
+          qrSize: 100,
+        },
+        {
+          label: "25×25mm",
+          value: "small",
+          width: 20,
+          height: 20,
+          marginTop: 0,
+          marginLeft: 0,
+          qrSize: 30,
+        },
+      ],
     };
   },
+  created() {
+    this.printer = new ArgoxPrinter();
+  },
   mounted() {
     this.GET_WarehouseList();
     this.GET_DeptList();
     // this.GET_StationAllList()
     this.GET_AdministratorList();
   },
-  watch: {},
+  watch: {
+    PrintVisible(newVal) {
+      if (newVal) {
+        this.$nextTick(() => {
+          this.generateBarcodes();
+        });
+      }
+    },
+    selectedSize() {
+      this.$nextTick(() => {
+        this.generateBarcodes();
+      });
+    },
+    qrCodeSelectedSize: {
+      handler(newSize) {
+        this.$nextTick(() => {
+          this.generateQRCodes();
+        });
+      }
+    }
+  },
   computed: {
     ...mapGetters(["user"]),
+    barcodeOptions() {
+      const options = {
+        format: "CODE128",
+        width: 2,
+        height: 60,
+        displayValue: false,
+      };
+      if (this.selectedSize === "medium") {
+        options.width = 1.5;
+        options.height = 45;
+      } else if (this.selectedSize === "small") {
+        options.width = 1;
+        options.height = 30;
+      }
+      return options;
+    },
   },
   methods: {
+    searchAdd() {
+      // Reset pagination
+      this.params.page_no = 1;
+
+      // Add search parameters
+      this.params = {
+        ...this.params,
+        keyword: this.searchForm.sn,
+        sku: this.searchForm.sku,
+        name: this.searchForm.goods_name,
+      };
+
+      // Call API with updated params
+      API_Setting.getSnProduct(this.params)
+        .then((res) => {
+          this.snTableData = res;
+        })
+        .catch((err) => {
+          this.$message.error("搜索失败:" + err.message);
+        });
+    },
+
+    /* 重置搜索 */
+    resetSearch() {
+      this.searchForm = {
+        sn: "",
+        sku: "",
+        goods_name: "",
+      };
+      this.params = {
+        page_no: 1,
+        page_size: 10,
+      };
+      this.searchAdd();
+    },
+
+    /* 打印 */
+    generateBarcodes() {
+      const options = this.getBarcodeOptions();
+      this.codeList.forEach((item, index) => {
+        JsBarcode(`#barcode-${index}`, item, options);
+      });
+    },
+    getBarcodeOptions() {
+      const sizeConfig = {
+        custom: { width: 1.2, height: 30 }, // 添加自定义尺寸配置
+        large: { width: 1.5, height: 40 },
+        medium: { width: 1.2, height: 20 },
+        small: { width: 1, height: 15 },
+      };
+      const { width, height } = sizeConfig[this.selectedSize];
+      return {
+        format: "CODE128",
+        width,
+        height,
+        displayValue: false,
+        margin: 5,
+      };
+    },
+    // 修改打印方法
+    async handlePrintGoodsLend() {
+      try {
+        if (!this.selectedSize) {
+          this.$message.warning("请先选择打印尺寸");
+          return;
+        }
+
+        const selectedOption = this.sizeOptions.find(
+          (option) => option.value === this.selectedSize
+        );
+        if (!selectedOption) {
+          throw new Error("无效的打印尺寸");
+        }
+
+        await this.generateBarcodes();
+
+        const printContent = this.codeList
+          .map((code, index) => {
+            const barcodeElement = document.getElementById(`barcode-${index}`);
+            if (!barcodeElement) {
+              throw new Error("条形码生成失败");
+            }
+            return `
+            <div class="print-content">
+              <div class="barcode-container">
+                ${barcodeElement.outerHTML}
+              </div>
+              <div class="text">${String(code).toUpperCase()}</div>
+            </div>
+          `;
+          })
+          .join("");
+
+        this.printer.print(printContent, {
+          width: selectedOption.width,
+          height: selectedOption.height,
+          marginTop: selectedOption.marginTop,
+          marginLeft: selectedOption.marginLeft,
+          fontSize: selectedOption.fontSize,
+        });
+
+        this.$message.success("打印成功");
+        this.PrintVisible = false;
+      } catch (error) {
+        this.$message.error("打印失败:" + error.message);
+      }
+    },
     warehouseName(val) {
       let name = "";
-      this.warehouseList.map((el) => {
-        if (el.id == val) {
-          return (name = el.name);
-        }
-      });
+      if (Array.isArray(this.warehouseList) && this.warehouseList.length > 0) {
+        this.warehouseList.forEach((el) => {
+          if (el.id == val) {
+            name = el.name;
+          }
+        });
+      }
       return name;
     },
     snCodeCancle() {
@@ -432,14 +834,14 @@ export default {
       this.PrintVisible = true;
     },
     /** 打印对账详情 */
-    handlePrintGoodsLend() {
+    /* handlePrintGoodsLend() {
       Print({
         printable: "deliverySheet",
         type: "html",
         targetStyles: ["*"],
         ignoreElements: ["no-logs", "goods-image", "no-btn"],
       });
-    },
+    }, */
     handleCancle() {
       this.PrintVisible = false;
       this.codeList = [];
@@ -588,6 +990,7 @@ export default {
       this.params = {
         ...this.params,
         ...this.advancedForm,
+        name: this.advancedForm.goods_name, // Add goods_name to search params
       };
       this.params.page_no = 1;
       this.GET_WarehouseList();
@@ -611,6 +1014,92 @@ export default {
         this.warehouseList = response;
       });
     },
+    // 批量二维码打印
+    qRcode() {
+      if (this.multipleSelection.length === 0) {
+        this.$message.warning("请先选择要打印的序列号");
+        return;
+      }
+
+      this.qrCodeList = this.multipleSelection.map((item) => item.sn_code);
+      this.qrCodeVisible = true;
+      this.$nextTick(() => {
+        this.generateQRCodes();
+      });
+    },
+
+    // 生成二维码
+    generateQRCodes() {
+      this.qrCodeList.forEach((code, index) => {
+        const element = document.getElementById(`qrcode-${index}`);
+        if (element) {
+          element.innerHTML = ""; // 清除现有内容
+          
+          const selectedSize = this.qrCodeSizeOptions.find(
+            (option) => option.value === this.qrCodeSelectedSize
+          );
+          
+          new QRCode(element, {
+            text: code,
+            width: selectedSize.qrSize,
+            height: selectedSize.qrSize,
+            colorDark: "#000000",
+            colorLight: "#ffffff",
+            correctLevel: QRCode.CorrectLevel.H
+          });
+        }
+      });
+    },
+
+    // 打印二维码
+    handleQRCodePrint() {
+      try {
+        const selectedOption = this.qrCodeSizeOptions.find(
+          (option) => option.value === this.qrCodeSelectedSize
+        );
+
+        const printContent = this.qrCodeList
+          .map((code, index) => {
+            const qrcodeElement = document.getElementById(`qrcode-${index}`);
+            return `
+              <div class="print-content">
+                <div class="qrcode-container">
+                  ${qrcodeElement ? qrcodeElement.outerHTML : ""}
+                </div>
+              </div>
+            `;
+          })
+          .join("");
+
+        this.printer.print(printContent, {
+          width: selectedOption.width,
+          height: selectedOption.height,
+          marginTop: selectedOption.marginTop,
+          marginLeft: selectedOption.marginLeft,
+          fontSize: 12,
+        });
+
+        this.$message.success("打印成功");
+        this.qrCodeVisible = false;
+      } catch (error) {
+        this.$message.error("打印失败:" + error.message);
+      }
+    },
+
+    // 取消二维码打印
+    handleQRCodeCancel() {
+      this.qrCodeVisible = false;
+      this.qrCodeList = [];
+    },
+
+    // 单个二维码打印
+    handleSingleQRCode(row) {
+      this.qrCodeList = [row.sn_code];
+      this.qrCodeVisible = true;
+      this.$nextTick(() => {
+        this.generateQRCodes();
+      });
+    },
   },
 };
 </script>
@@ -712,4 +1201,201 @@ export default {
     text-align: center;
   }
 }
+.print-preview-container {
+  overflow: auto;
+  width: 100%;
+  height: 400px;
+  display: flex;
+  justify-content: center;
+  align-items: flex-start;
+
+  &.portrait {
+    #deliverySheet {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+    }
+
+    .tips-t {
+      width: v-bind(
+        'selectedSize === "large" ? "95mm" : selectedSize === "medium" ? "55mm" : "13mm"'
+      );
+      height: v-bind('selectedSize === "small" ? "50mm" : "35mm"');
+    }
+  }
+
+  &.landscape {
+    #deliverySheet {
+      display: flex;
+      flex-wrap: wrap;
+      justify-content: flex-start;
+    }
+
+    .tips-t {
+      width: v-bind('selectedSize === "small" ? "50mm" : "35mm"');
+      height: v-bind(
+        'selectedSize === "large" ? "95mm" : selectedSize === "medium" ? "55mm" : "13mm"'
+      );
+      margin-right: 2mm;
+    }
+  }
+}
+
+#deliverySheet {
+  transform-origin: top left;
+}
+
+.tips-t {
+  border: 1px solid #ccc;
+  margin-bottom: 2mm;
+  padding: 2mm;
+  box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+
+  .content-wrapper {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+  }
+
+  .barcode-container {
+    width: 100%;
+    height: v-bind('selectedSize === "small" ? "60%" : "70%"');
+    display: flex;
+    justify-content: center;
+    align-items: center;
+
+    svg {
+      max-width: 100%;
+      max-height: 100%;
+    }
+  }
+
+  .numOrder {
+    font-size: v-bind('selectedSize === "small" ? "8px" : "14px"');
+    margin-top: 1mm;
+  }
+}
+
+.tips-t {
+  border: 1px solid #ccc;
+  margin-bottom: 2mm;
+  padding: 1mm;
+  box-sizing: border-box;
+  /* width: 50mm;
+  height: 20mm; */
+
+  .content-wrapper {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+  }
+
+  .barcode-container {
+    width: 100%;
+    height: 12mm;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    margin-top: 1mm;
+
+    svg {
+      width: 45mm;
+      height: 12mm;
+    }
+  }
+
+  .numOrder {
+    font-size: 8pt;
+    margin-top: 1mm;
+    height: 4mm;
+    line-height: 4mm;
+    text-align: center;
+  }
+}
+
+// 打印时的样式覆盖
+@media print {
+  @page {
+    size: 50mm 20mm;
+    margin: 0;
+  }
+
+  .tips-t {
+    page-break-after: always;
+    border: none;
+  }
+}
+@media print {
+  @page {
+    size: auto;
+    margin: 0;
+  }
+
+  body {
+    margin: 0;
+  }
+
+  .print-options,
+  .dialog-footer {
+    display: none;
+  }
+
+  #deliverySheet {
+    transform: none !important;
+  }
+
+  .tips-t {
+    page-break-inside: avoid;
+    margin-bottom: 0;
+  }
+}
+.header {
+  padding: 10px;
+
+  .el-form {
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+
+    .el-form-item {
+      margin-bottom: 10px;
+      margin-right: 10px;
+      display: flex;
+      align-items: center;
+      .el-input {
+        width: 200px;
+      }
+    }
+  }
+}
+.print-preview-container {
+  overflow: auto;
+  width: 100%;
+  height: 400px;
+  display: flex;
+  justify-content: center;
+  align-items: flex-start;
+}
+.qrcode-container {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 100%;
+  height: 100%;
+  
+  canvas {
+    max-width: 100%;
+    max-height: 100%;
+  }
+}
 </style>

+ 168 - 63
manager-admin/src/views/stock/goodsExchange/goodsExchange.vue

@@ -6,16 +6,24 @@
         <el-tab-pane label="出库明细" name="first"></el-tab-pane>
       </el-tabs>
     </div>
-    <div class="btn">
-    </div>
+    <div class="btn"></div>
     <div class="search">
       <el-form ref="advancedForm" :model="advancedForm" label-width="160px">
         <el-row>
-          <el-col :span="activeName=='first'?12:8">
+          <el-col :span="activeName == 'first' ? 12 : 8">
             <el-form-item label="出入时间">
-              <el-date-picker v-model="advancedForm.goodsExchange_time_range" type="daterange" align="center"
-                :editable="false" unlink-panels :clearable="true" :default-time="['00:00:00', '23:59:59']"
-                range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" value-format="timestamp"
+              <el-date-picker
+                v-model="advancedForm.goodsExchange_time_range"
+                type="daterange"
+                align="center"
+                :editable="false"
+                unlink-panels
+                :clearable="true"
+                :default-time="['00:00:00', '23:59:59']"
+                range-separator="-"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                value-format="timestamp"
                 :picker-options="{
                   disabledDate(time) {
                     return (
@@ -25,37 +33,56 @@
                         new Date().getMonth(),
                         new Date().getDate()
                       ).getTime() +
-                      86400000 -
-                      1
+                        86400000 -
+                        1
                     );
                   },
                   shortcuts: MixinPickerShortcuts,
-                }">
+                }"
+              >
               </el-date-picker>
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="仓库">
               <el-select v-model="advancedForm.warehouse_id" clearable>
-                <el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
+                <el-option
+                  v-for="item in warehouseList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="6" v-if="activeName == 'second'">
             <el-form-item label="入库类型">
               <el-select v-model="advancedForm.type" clearable>
-                <el-option v-for="item in entryList" :key="item.id" :label="item.label" :value="item.value" />
+                <el-option
+                  v-for="item in entryList"
+                  :key="item.id"
+                  :label="item.label"
+                  :value="item.value"
+                />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="8" v-if="activeName == 'second'">
             <el-form-item label="客户名称">
-              <el-input v-model="advancedForm.customer_name" clearable placeholder="请输入客户名称"></el-input>
+              <el-input
+                v-model="advancedForm.customer_name"
+                clearable
+                placeholder="请输入客户名称"
+              ></el-input>
             </el-form-item>
           </el-col>
           <el-col :span="8" v-if="activeName == 'second'">
             <el-form-item label="手机号">
-              <el-input v-model="advancedForm.customer_phone" clearable placeholder="请输入手机号"></el-input>
+              <el-input
+                v-model="advancedForm.customer_phone"
+                clearable
+                placeholder="请输入手机号"
+              ></el-input>
             </el-form-item>
           </el-col>
         </el-row>
@@ -63,15 +90,29 @@
       <el-button @click="advancedSearchEvent"> 搜索 </el-button>
     </div>
 
-    <en-table-layout :tableData="tableData.data" :loading="loading" @selection-change="handleSelectionChange">
+    <en-table-layout
+      :tableData="tableData.data"
+      :loading="loading"
+      @selection-change="handleSelectionChange"
+    >
       <div slot="toolbar" class="inner-toolbar">
         <div class="toolbar-btns">
-          <el-button size="mini" v-if="
-            checkPermission(['addInventory']) && activeName == 'second'
-          " type="primary" @click="handleAddGoodsExchange">新增入库</el-button>
-          <el-button size="mini" v-if="
-            checkPermission(['goodsExchangeAdd']) && activeName == 'first'
-          " type="primary" @click="handleShiftGoodsExchange">新增出库</el-button>
+          <el-button
+            size="mini"
+            v-if="checkPermission(['addInventory']) && activeName == 'second'"
+            type="primary"
+            @click="handleAddGoodsExchange"
+            >新增入库</el-button
+          >
+          <el-button
+            size="mini"
+            v-if="
+              checkPermission(['goodsExchangeAdd']) && activeName == 'first'
+            "
+            type="primary"
+            @click="handleShiftGoodsExchange"
+            >新增出库</el-button
+          >
           <!-- <el-button
             v-if="checkPermission(['goodsExchange:del'])"
             size="mini"
@@ -85,7 +126,11 @@
 
       <template slot="table-columns">
         <el-table-column type="selection" width="55" />
-        <el-table-column v-if="activeName == 'first'" prop="sn" label="出库单号">
+        <el-table-column
+          v-if="activeName == 'first'"
+          prop="sn"
+          label="出库单号"
+        >
           <template slot-scope="scope">
             {{ scope.row.sn }}
           </template>
@@ -110,7 +155,11 @@
             {{ scope.row.customer_phone }}
           </template>
         </el-table-column>
-        <el-table-column prop="memo" label="出库类型" v-if="activeName == 'first'">
+        <el-table-column
+          prop="memo"
+          label="出库类型"
+          v-if="activeName == 'first'"
+        >
           <template slot-scope="scope">
             <span>{{ outName(scope.row.type) }}</span>
           </template>
@@ -120,7 +169,11 @@
             <span>{{ entryName(scope.row.type) }}</span>
           </template>
         </el-table-column>
-        <el-table-column prop="memo" label="入库时间" v-if="activeName == 'second'">
+        <el-table-column
+          prop="memo"
+          label="入库时间"
+          v-if="activeName == 'second'"
+        >
           <template slot-scope="scope">
             <span>{{ scope.row.create_time | unixToDate }}</span>
           </template>
@@ -128,15 +181,24 @@
         <el-table-column prop="order_id_list" label="订单编号" />
         <el-table-column label="状态">
           <template slot-scope="scope">
-            <span v-if="activeName == 'first'">{{ scope.row.has_submit == 'Y' ? '已出库' : '未出库' }}</span>
-            <span v-else>{{ scope.row.has_submit == 'Y' ? '已入库' : '未入库' }}</span>
+            <span v-if="activeName == 'first'">{{
+              scope.row.has_submit == "Y" ? "已出库" : "未出库"
+            }}</span>
+            <span v-else>{{
+              scope.row.has_submit == "Y" ? "已入库" : "未入库"
+            }}</span>
           </template>
         </el-table-column>
-        <el-table-column prop="memo" label="出库时间" v-if="activeName == 'first'">
+        <el-table-column
+          prop="memo"
+          label="出库时间"
+          v-if="activeName == 'first'"
+        >
           <template slot-scope="scope">
             <span>{{ scope.row.create_time | unixToDate }}</span>
           </template>
         </el-table-column>
+        <el-table-column prop="goodsName" label="商品名称"></el-table-column>
         <el-table-column prop="memo" label="备注">
           <template slot-scope="scope">
             <span v-if="activeName == 'first'">{{ scope.row.notes }}</span>
@@ -145,21 +207,49 @@
         </el-table-column>
         <el-table-column label="操作" width="450">
           <template slot-scope="scope">
-            <el-button size="mini" v-if="checkPermission(['checkInventory'])"
-              @click="handleAuditGoodsExchange(scope.row)">查看</el-button>
-            <el-button size="mini"
-              v-if="scope.row.has_submit == 'N' && checkPermission(['editInventory']) && checkPermission(['goodsExchangeEdit']) && activeName == 'first'"
-              @click="handleEditGoodsExchange(scope.row)">出库</el-button>
-            <el-button size="mini"
-              v-if="scope.row.has_submit == 'N' && checkPermission(['editInventory']) && checkPermission(['goodsExchangeEdit']) && activeName == 'second'"
-              @click="handleEditGoodsExchange(scope.row)">入库</el-button>
+            <el-button
+              size="mini"
+              v-if="checkPermission(['checkInventory'])"
+              @click="handleAuditGoodsExchange(scope.row)"
+              >查看</el-button
+            >
+            <el-button
+              size="mini"
+              v-if="
+                scope.row.has_submit == 'N' &&
+                checkPermission(['editInventory']) &&
+                checkPermission(['goodsExchangeEdit']) &&
+                activeName == 'first'
+              "
+              @click="handleEditGoodsExchange(scope.row)"
+              >出库</el-button
+            >
+            <el-button
+              size="mini"
+              v-if="
+                scope.row.has_submit == 'N' &&
+                checkPermission(['editInventory']) &&
+                checkPermission(['goodsExchangeEdit']) &&
+                activeName == 'second'
+              "
+              @click="handleEditGoodsExchange(scope.row)"
+              >入库</el-button
+            >
           </template>
         </el-table-column>
       </template>
 
-      <el-pagination v-if="tableData" slot="pagination" @size-change="handlePageSizeChange"
-        @current-change="handlePageCurrentChange" :current-page="tableData.page_no" :page-sizes="[10, 20, 50, 100]"
-        :page-size="tableData.page_size" layout="total, sizes, prev, pager, next, jumper" :total="tableData.data_total">
+      <el-pagination
+        v-if="tableData"
+        slot="pagination"
+        @size-change="handlePageSizeChange"
+        @current-change="handlePageCurrentChange"
+        :current-page="tableData.page_no"
+        :page-sizes="[10, 20, 50, 100]"
+        :page-size="tableData.page_size"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="tableData.data_total"
+      >
       </el-pagination>
     </en-table-layout>
   </div>
@@ -195,14 +285,14 @@ export default {
       goodsExchangeForm: {},
       activeName: "second",
       entryList: [],
-      outList: []
+      outList: [],
     };
   },
   mounted() {
-    if (this.activeName == 'first') {
+    if (this.activeName == "first") {
       this.GET_GoodsExchangeList();
     } else {
-      this.GET_WarehouseEntry()
+      this.GET_WarehouseEntry();
     }
     this.GET_DeptList();
     this.GET_WarehouseList();
@@ -210,48 +300,48 @@ export default {
   watch: {
     $route: function ({ query }) {
       this.params.page_no = 1;
-      if (this.activeName == 'first') {
+      if (this.activeName == "first") {
         this.GET_GoodsExchangeList();
       } else {
-        this.GET_WarehouseEntry()
+        this.GET_WarehouseEntry();
       }
     },
   },
   methods: {
     //获取仓库名称
     outName(val) {
-      let name = ''
-      this.outList.map(el => {
+      let name = "";
+      this.outList.map((el) => {
         if (el.value == val) {
-          return name = el.label
+          return (name = el.label);
         }
-      })
-      return name
+      });
+      return name;
     },
     //获取仓库名称
     entryName(val) {
-      let name = ''
-      this.entryList.map(el => {
+      let name = "";
+      this.entryList.map((el) => {
         if (el.value == val) {
-          return name = el.label
+          return (name = el.label);
         }
-      })
-      return name
+      });
+      return name;
     },
     //获取仓库名称
     warehouseName(val) {
-      let name = ''
-      this.warehouseList.map(el => {
+      let name = "";
+      this.warehouseList.map((el) => {
         if (el.id == val) {
-          return name = el.name
+          return (name = el.name);
         }
-      })
-      return name
+      });
+      return name;
     },
 
     handleClick(tab, event) {
       this.activeName = tab.name;
-      this.params.page_no = 1
+      this.params.page_no = 1;
       if (tab.name == "first") {
         this.GET_GoodsExchangeList();
       } else {
@@ -292,7 +382,6 @@ export default {
           params: { id: row.id },
         });
       }
-
     },
     /** 提交审核 */
     handleSubmitGoodsExchange(row) {
@@ -317,7 +406,8 @@ export default {
             type: this.activeName,
           },
         });
-      } else {//auditInventory
+      } else {
+        //auditInventory
         this.$router.push({
           name: "checkInventory",
           params: {
@@ -326,7 +416,6 @@ export default {
           },
         });
       }
-
     },
     /** 获取仓库 */
     GET_WarehouseList() {
@@ -368,7 +457,7 @@ export default {
             this.GET_GoodsExchangeList();
           });
         })
-        .catch(() => { });
+        .catch(() => {});
     },
     /** 多选改变 */
     handleSelectionChange(val) {
@@ -478,7 +567,23 @@ export default {
       API_GoodsExchange.getWarehouseEntry(this.params)
         .then((response) => {
           this.loading = false;
-          this.tableData = response;
+          // 使用 Promise.all 处理所有异步请求
+          Promise.all(
+            response.data.map((el) => {
+              return API_GoodsExchange.getGoodsExchangeInfo(el.id).then(
+                (res) => {
+                  // 使用 map 获取所有商品名称,然后用逗号连接
+                  el.goodsName = res.product_list
+                    .map((e) => e.product_vo.name)
+                    .join(", ");
+                  return el;
+                }
+              );
+            })
+          ).then(() => {
+            console.log(response);
+            this.tableData = response;
+          });
         })
         .catch(() => {
           this.loading = false;

+ 2 - 2
manager-admin/src/views/stock/order.vue

@@ -38,7 +38,7 @@
           </el-col>
           <el-col :span="8">
             <el-form-item label="订单编号">
-              <el-input v-model="advancedForm.sn" placeholder="请输入订单编号"></el-input>
+              <el-input v-model="advancedForm.sn" placeholder="请输入订单编号" clearable></el-input>
             </el-form-item>
           </el-col>
         </el-row>
@@ -111,7 +111,7 @@
         </el-table-column>
         <el-table-column label="客户">
           <template slot-scope="scope">{{
-            memberType(scope.row.member_id)
+            memberType(scope.row.member_id) || scope.row.customer_name
           }}</template>
         </el-table-column>
         <el-table-column label="下单时间">

+ 2 - 2
manager-admin/src/views/stock/sendOrder.vue

@@ -63,7 +63,7 @@
         <el-table-column type="selection" width="55" />
         <el-table-column prop="" label="订单编号">
           <template slot-scope="scope">
-            {{ scope.row.sn }}
+            {{ scope.row.order_vo.sn }}
           </template>
         </el-table-column>
         <el-table-column prop="sn" label="出库单编号" v-if="params.selectType == 'sending'">
@@ -73,7 +73,7 @@
         </el-table-column>
         <el-table-column label="客户">
           <template slot-scope="scope">
-            {{ memberType(scope.row.order_vo.member_id) }}
+            {{ memberType(scope.row.order_vo.member_id)|| scope.row.order_vo.customer_name}}
           </template>
         </el-table-column>
         <el-table-column prop="order_time" label="下单时间">

+ 0 - 10
node_modules/.yarn-integrity

@@ -1,10 +0,0 @@
-{
-  "systemParams": "win32-x64-115",
-  "modulesFolders": [],
-  "flags": [],
-  "linkedModules": [],
-  "topLevelPatterns": [],
-  "lockfileEntries": {},
-  "files": [],
-  "artifacts": {}
-}

+ 165 - 1
package-lock.json

@@ -2,5 +2,169 @@
   "name": "magic-erp-ui",
   "lockfileVersion": 3,
   "requires": true,
-  "packages": {}
+  "packages": {
+    "": {
+      "dependencies": {
+        "vue-print-nb": "^1.7.5"
+      }
+    },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+      "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+      "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.26.2",
+      "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.2.tgz",
+      "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
+      "dependencies": {
+        "@babel/types": "^7.26.0"
+      },
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@vue/compiler-sfc": {
+      "version": "2.7.16",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz",
+      "integrity": "sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==",
+      "dependencies": {
+        "@babel/parser": "^7.23.5",
+        "postcss": "^8.4.14",
+        "source-map": "^0.6.1"
+      },
+      "optionalDependencies": {
+        "prettier": "^1.18.2 || ^2.0.0"
+      }
+    },
+    "node_modules/csstype": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
+      "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.7",
+      "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz",
+      "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
+    },
+    "node_modules/postcss": {
+      "version": "8.4.47",
+      "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.47.tgz",
+      "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "nanoid": "^3.3.7",
+        "picocolors": "^1.1.0",
+        "source-map-js": "^1.2.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/prettier": {
+      "version": "2.8.8",
+      "resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.8.8.tgz",
+      "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+      "optional": true,
+      "bin": {
+        "prettier": "bin-prettier.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "url": "https://github.com/prettier/prettier?sponsor=1"
+      }
+    },
+    "node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/vue": {
+      "version": "2.7.16",
+      "resolved": "https://registry.npmmirror.com/vue/-/vue-2.7.16.tgz",
+      "integrity": "sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==",
+      "deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.",
+      "dependencies": {
+        "@vue/compiler-sfc": "2.7.16",
+        "csstype": "^3.1.0"
+      }
+    },
+    "node_modules/vue-print-nb": {
+      "version": "1.7.5",
+      "resolved": "https://registry.npmmirror.com/vue-print-nb/-/vue-print-nb-1.7.5.tgz",
+      "integrity": "sha512-iNbNyUVRWz0Ha1UTiCKxMPtHLUDGgNI8e8xmD3xqm9RlXIUeX9bT7DgNAfY8vPzqyFRHqGjxLI1rycKH366ziQ==",
+      "dependencies": {
+        "vue": "^2.6.11"
+      }
+    }
+  }
 }

+ 3 - 1
package.json

@@ -1,3 +1,5 @@
 {
-  "dependencies": {}
+  "dependencies": {
+    "vue-print-nb": "^1.7.5"
+  }
 }

+ 3 - 3
ui-domain/api.js

@@ -9,14 +9,14 @@
 module.exports = {
   // 开发环境 192.168.8.103:9999
   dev: {
-    admin: window.__ENV__.API_ADMIN || 'http://192.168.8.102:9999'//https://apidoc.raycos.net http://192.168.8.103:9999
+    admin: window.__ENV__.API_ADMIN || 'http://apidoc.raycos.net'//https://apidoc.raycos.net http://192.168.8.103:9999
   },
   // 测试环境apidoc.raycos.net 60.204.236.53:9999
   test: {
-    admin: window.__ENV__.API_ADMIN || 'http://127.0.0.1:9999'
+    admin: window.__ENV__.API_ADMIN || 'http://apidoc.raycos.net'
   },
   // 生产环境
   pro: {
-    admin: window.__ENV__.API_ADMIN || 'http://127.0.0.1:9999'//http://apidoc.raycos.net
+    admin: window.__ENV__.API_ADMIN || 'http://apidoc.raycos.net'//http://apidoc.raycos.net
   }
 }

+ 89 - 0
yarn.lock

@@ -2,3 +2,92 @@
 # yarn lockfile v1
 
 
+"@babel/helper-string-parser@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz"
+  integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
+
+"@babel/helper-validator-identifier@^7.25.9":
+  version "7.25.9"
+  resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz"
+  integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
+
+"@babel/parser@^7.23.5":
+  version "7.26.2"
+  resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.2.tgz"
+  integrity sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==
+  dependencies:
+    "@babel/types" "^7.26.0"
+
+"@babel/types@^7.26.0":
+  version "7.26.0"
+  resolved "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz"
+  integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==
+  dependencies:
+    "@babel/helper-string-parser" "^7.25.9"
+    "@babel/helper-validator-identifier" "^7.25.9"
+
+"@vue/compiler-sfc@2.7.16":
+  version "2.7.16"
+  resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz"
+  integrity sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==
+  dependencies:
+    "@babel/parser" "^7.23.5"
+    postcss "^8.4.14"
+    source-map "^0.6.1"
+  optionalDependencies:
+    prettier "^1.18.2 || ^2.0.0"
+
+csstype@^3.1.0:
+  version "3.1.3"
+  resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz"
+  integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
+
+nanoid@^3.3.7:
+  version "3.3.7"
+  resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz"
+  integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
+
+picocolors@^1.1.0:
+  version "1.1.1"
+  resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz"
+  integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
+
+postcss@^8.4.14:
+  version "8.4.47"
+  resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.47.tgz"
+  integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==
+  dependencies:
+    nanoid "^3.3.7"
+    picocolors "^1.1.0"
+    source-map-js "^1.2.1"
+
+"prettier@^1.18.2 || ^2.0.0":
+  version "2.8.8"
+  resolved "https://registry.npmmirror.com/prettier/-/prettier-2.8.8.tgz"
+  integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
+
+source-map-js@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz"
+  integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
+
+source-map@^0.6.1:
+  version "0.6.1"
+  resolved "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz"
+  integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
+vue-print-nb@^1.7.5:
+  version "1.7.5"
+  resolved "https://registry.npmmirror.com/vue-print-nb/-/vue-print-nb-1.7.5.tgz"
+  integrity sha512-iNbNyUVRWz0Ha1UTiCKxMPtHLUDGgNI8e8xmD3xqm9RlXIUeX9bT7DgNAfY8vPzqyFRHqGjxLI1rycKH366ziQ==
+  dependencies:
+    vue "^2.6.11"
+
+vue@^2.6.11:
+  version "2.7.16"
+  resolved "https://registry.npmmirror.com/vue/-/vue-2.7.16.tgz"
+  integrity sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==
+  dependencies:
+    "@vue/compiler-sfc" "2.7.16"
+    csstype "^3.1.0"

Some files were not shown because too many files changed in this diff