Selaa lähdekoodia

一体机长链接修改调试

asd26269546 2 vuotta sitten
vanhempi
commit
60953d5449
53 muutettua tiedostoa jossa 3069 lisäystä ja 1135 poistoa
  1. 1 0
      dist1/css/app.c3f4e3ca.css
  2. 0 0
      dist1/css/chunk-25fe99da.d1c071e3.css
  3. 1 0
      dist1/css/chunk-439966e0.c226e69e.css
  4. 0 0
      dist1/css/chunk-4c732b19.81fdd7e7.css
  5. 0 0
      dist1/css/chunk-5190983c.05b33d15.css
  6. 1 0
      dist1/css/chunk-743c3027.ef5aa059.css
  7. 1 0
      dist1/css/chunk-c89bae56.ec9984c3.css
  8. 0 0
      dist1/css/chunk-ea83faca.7abf6d3f.css
  9. 0 0
      dist1/css/chunk-vendors.5cbbb097.css
  10. BIN
      dist1/css/chunk-vendors.5cbbb097.css.gz
  11. BIN
      dist1/fonts/ionicons.143146fa.woff2
  12. BIN
      dist1/fonts/ionicons.99ac3308.woff
  13. BIN
      dist1/fonts/ionicons.99ac3308.woff.gz
  14. BIN
      dist1/fonts/ionicons.d535a25a.ttf
  15. BIN
      dist1/fonts/ionicons.d535a25a.ttf.gz
  16. BIN
      dist1/img/avator.cecc4b55.png
  17. BIN
      dist1/img/bg.4dd868a1.jpg
  18. BIN
      dist1/img/border.a6b7a1bd.png
  19. BIN
      dist1/img/in.67773ecf.png
  20. 24 0
      dist1/img/ionicons.a2c4a261.svg
  21. BIN
      dist1/img/ionicons.a2c4a261.svg.gz
  22. BIN
      dist1/img/out.580e5c5c.png
  23. BIN
      dist1/img/stock.eff15400.png
  24. 1 0
      dist1/index.html
  25. 0 0
      dist1/js/app.1668695772318.js
  26. BIN
      dist1/js/app.1668695772318.js.gz
  27. 0 0
      dist1/js/chunk-25fe99da.1668695772318.js
  28. BIN
      dist1/js/chunk-25fe99da.1668695772318.js.gz
  29. 0 0
      dist1/js/chunk-439966e0.1668695772318.js
  30. 0 0
      dist1/js/chunk-4b928543.1668695772318.js
  31. BIN
      dist1/js/chunk-4b928543.1668695772318.js.gz
  32. 0 0
      dist1/js/chunk-4c732b19.1668695772318.js
  33. BIN
      dist1/js/chunk-4c732b19.1668695772318.js.gz
  34. 0 0
      dist1/js/chunk-5190983c.1668695772318.js
  35. BIN
      dist1/js/chunk-5190983c.1668695772318.js.gz
  36. 0 0
      dist1/js/chunk-743c3027.1668695772318.js
  37. 0 0
      dist1/js/chunk-c89bae56.1668695772318.js
  38. 0 0
      dist1/js/chunk-ea83faca.1668695772318.js
  39. BIN
      dist1/js/chunk-ea83faca.1668695772318.js.gz
  40. 0 0
      dist1/js/chunk-vendors.1668695772318.js
  41. BIN
      dist1/js/chunk-vendors.1668695772318.js.gz
  42. BIN
      dist1/logo.png
  43. 1 0
      dist1/version.json
  44. 10 0
      src/App.vue
  45. 1 1
      src/components/my-modal-form/my-modal-material.vue
  46. 2 2
      src/components/my-nav.vue
  47. 12 2
      src/router/routers.js
  48. 2 2
      src/views/Home.vue
  49. 191 57
      src/views/store-change.vue
  50. 760 537
      src/views/store-in - 副本 (2).vue
  51. 0 534
      src/views/store-in - 副本.vue
  52. 1051 0
      src/views/store-in-2.vue
  53. 1010 0
      src/views/store-out-2.vue

+ 1 - 0
dist1/css/app.c3f4e3ca.css

@@ -0,0 +1 @@
+#app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#2c3e50}#nav{padding:30px}#nav a{font-weight:700;color:#2c3e50}#nav a.router-link-exact-active{color:#42b983}.container[data-v-4ed82897]{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100vw;height:100vh;min-width:500px;min-height:400px;background-image:linear-gradient(270deg,#2c3034,#50575e 49%,#2c3034)}.container .title[data-v-4ed82897]{font-size:4vw;font-weight:700;color:#fff}.container .sub-title[data-v-4ed82897]{padding-bottom:20px;font-size:2vw;font-weight:700;color:#fff}.container .menu[data-v-4ed82897]{display:flex;align-items:center;justify-content:space-between}.container .menu .item[data-v-4ed82897]{display:flex;flex-direction:column;align-items:center;justify-content:center;margin-right:3vw;width:15vw;height:20vw;min-width:190px;min-height:250px;background-color:#fff;border-radius:10px;cursor:pointer}.container .menu .item[data-v-4ed82897]:last-child{margin-right:0}.container .menu .item img[data-v-4ed82897]{width:60%}.container .menu .item .label[data-v-4ed82897]{padding-top:30px;font-size:2vw;font-weight:700}.container .menu .item .label.green[data-v-4ed82897]{color:#4b7902}.container .menu .item .label.blue[data-v-4ed82897]{color:navy}.container .menu .item .label.other[data-v-4ed82897]{color:#8bde06}.btn[data-v-4ed82897]{position:fixed;top:20px;right:20px}.store[data-v-4ed82897]{position:fixed;top:20px;left:50%;transform:translateX(-50%);height:32px;line-height:32px;font-size:32px;font-weight:700;color:#fff}.ivu-spin-fix{background-color:transparent}.vertical-center-modal{display:flex;align-items:center;justify-content:center}.vertical-center-modal .ivu-modal{top:0}

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/css/chunk-25fe99da.d1c071e3.css


+ 1 - 0
dist1/css/chunk-439966e0.c226e69e.css

@@ -0,0 +1 @@
+.container[data-v-239d275d]{height:100%}.container .table-filter[data-v-239d275d]{padding-bottom:10px;height:42px;line-height:32px;overflow:hidden}.container .table-filter .filter-item[data-v-239d275d]{margin-right:10px;float:left}.container .table-content[data-v-239d275d]{overflow:auto}.container .table-page[data-v-239d275d]{padding-top:10px;display:flex;justify-content:center;align-items:center;height:43px;overflow:hidden}[data-v-239d275d] .select-row-bg{background:#ebf7ff}[data-v-239d275d] .select-row-bg td{background:transparent}[data-v-239d275d] .select-row-bg-red{background:#ebf7ff}[data-v-239d275d] .select-row-bg-red td{background:#ffe7e7;color:#6e6e6e}.container[data-v-74dd8043]{padding:10px 0}

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/css/chunk-4c732b19.81fdd7e7.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/css/chunk-5190983c.05b33d15.css


+ 1 - 0
dist1/css/chunk-743c3027.ef5aa059.css

@@ -0,0 +1 @@
+.container[data-v-6bc5986a]{position:relative;width:100vw;height:100vh;min-width:500px;min-height:400px;background-repeat:no-repeat;background-size:cover}.container .tabs[data-v-6bc5986a]{position:absolute;bottom:0;left:0;width:100%;display:flex;justify-content:center;background:rgba(5,10,30,.5)}.container .tabs .tab[data-v-6bc5986a]{padding:20px 40px;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer}.container .tabs .tab.active[data-v-6bc5986a]{background:hsla(0,0%,100%,.2);transition:all .5s}.container .tabs .tab .label[data-v-6bc5986a]{padding:10px;font-size:18px;font-weight:700;color:#fff}.container .update-face[data-v-6bc5986a]{position:absolute;top:20px;left:20px;font-size:20px;font-weight:700;color:#fff}.form[data-v-6bc5986a]{z-index:999;padding:0 40px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:400px;border-radius:10px;background:rgba(0,0,0,.5)}.form .title[data-v-6bc5986a]{padding:20px 0;font-size:30px;font-weight:700;color:#fff}.form .btn[data-v-6bc5986a]{padding:20px 0}.tracking-wrap[data-v-6bc5986a]{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.tracking-wrap .border[data-v-6bc5986a]{position:absolute;top:-60px;left:-40px;width:700px;height:580px}.tracking-wrap .tracking[data-v-6bc5986a]{position:relative;width:620px;height:460px}.tracking-wrap .tracking>[data-v-6bc5986a]{position:absolute;left:0;top:0;border-radius:10px}.tracking-wrap .tracking canvas[data-v-6bc5986a],.tracking-wrap .tracking video[data-v-6bc5986a]{top:0}.back[data-v-6bc5986a]{position:fixed;top:20px;left:20px}

+ 1 - 0
dist1/css/chunk-c89bae56.ec9984c3.css

@@ -0,0 +1 @@
+.container[data-v-99578902]{position:relative;width:100vw;height:100vh;min-width:500px;min-height:400px;background-repeat:no-repeat;background-size:cover}.container .tabs[data-v-99578902]{position:absolute;bottom:0;left:0;width:100%;display:flex;justify-content:center;background:rgba(5,10,30,.5)}.container .tabs .tab[data-v-99578902]{padding:20px 40px;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer}.container .tabs .tab.active[data-v-99578902]{background:hsla(0,0%,100%,.2);transition:all .5s}.container .tabs .tab .label[data-v-99578902]{padding:10px;font-size:18px;font-weight:700;color:#fff}.container .update-face[data-v-99578902]{position:absolute;top:20px;left:20px;font-size:20px;font-weight:700;color:#fff}.form[data-v-99578902]{z-index:999;padding:0 40px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:400px;border-radius:10px;background:rgba(0,0,0,.5)}.form .title[data-v-99578902]{padding:20px 0;font-size:30px;font-weight:700;color:#fff}.form .btn[data-v-99578902]{padding:20px 0}.tracking-wrap[data-v-99578902]{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.tracking-wrap .border[data-v-99578902]{position:absolute;top:-60px;left:-40px;width:700px;height:580px}.tracking-wrap .tracking[data-v-99578902]{position:relative;width:620px;height:460px}.tracking-wrap .tracking>[data-v-99578902]{position:absolute;left:0;top:0;border-radius:10px}.tracking-wrap .tracking canvas[data-v-99578902],.tracking-wrap .tracking video[data-v-99578902]{top:0}.back[data-v-99578902]{position:fixed;top:20px;left:20px}

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/css/chunk-ea83faca.7abf6d3f.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/css/chunk-vendors.5cbbb097.css


BIN
dist1/css/chunk-vendors.5cbbb097.css.gz


BIN
dist1/fonts/ionicons.143146fa.woff2


BIN
dist1/fonts/ionicons.99ac3308.woff


BIN
dist1/fonts/ionicons.99ac3308.woff.gz


BIN
dist1/fonts/ionicons.d535a25a.ttf


BIN
dist1/fonts/ionicons.d535a25a.ttf.gz


BIN
dist1/img/avator.cecc4b55.png


BIN
dist1/img/bg.4dd868a1.jpg


BIN
dist1/img/border.a6b7a1bd.png


BIN
dist1/img/in.67773ecf.png


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 24 - 0
dist1/img/ionicons.a2c4a261.svg


BIN
dist1/img/ionicons.a2c4a261.svg.gz


BIN
dist1/img/out.580e5c5c.png


BIN
dist1/img/stock.eff15400.png


+ 1 - 0
dist1/index.html

@@ -0,0 +1 @@
+<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/logo.png"><title>智能仓储一体机</title><link href="/css/chunk-25fe99da.d1c071e3.css" rel="prefetch"><link href="/css/chunk-439966e0.c226e69e.css" rel="prefetch"><link href="/css/chunk-4c732b19.81fdd7e7.css" rel="prefetch"><link href="/css/chunk-5190983c.05b33d15.css" rel="prefetch"><link href="/css/chunk-743c3027.ef5aa059.css" rel="prefetch"><link href="/css/chunk-c89bae56.ec9984c3.css" rel="prefetch"><link href="/css/chunk-ea83faca.7abf6d3f.css" rel="prefetch"><link href="/js/chunk-25fe99da.1668695772318.js" rel="prefetch"><link href="/js/chunk-439966e0.1668695772318.js" rel="prefetch"><link href="/js/chunk-4b928543.1668695772318.js" rel="prefetch"><link href="/js/chunk-4c732b19.1668695772318.js" rel="prefetch"><link href="/js/chunk-5190983c.1668695772318.js" rel="prefetch"><link href="/js/chunk-743c3027.1668695772318.js" rel="prefetch"><link href="/js/chunk-c89bae56.1668695772318.js" rel="prefetch"><link href="/js/chunk-ea83faca.1668695772318.js" rel="prefetch"><link href="/css/app.c3f4e3ca.css" rel="preload" as="style"><link href="/css/chunk-vendors.5cbbb097.css" rel="preload" as="style"><link href="/js/app.1668695772318.js" rel="preload" as="script"><link href="/js/chunk-vendors.1668695772318.js" rel="preload" as="script"><link href="/css/chunk-vendors.5cbbb097.css" rel="stylesheet"><link href="/css/app.c3f4e3ca.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but 智能仓储一体机 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/js/chunk-vendors.1668695772318.js"></script><script src="/js/app.1668695772318.js"></script></body></html>

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/js/app.1668695772318.js


BIN
dist1/js/app.1668695772318.js.gz


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/js/chunk-25fe99da.1668695772318.js


BIN
dist1/js/chunk-25fe99da.1668695772318.js.gz


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/js/chunk-439966e0.1668695772318.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/js/chunk-4b928543.1668695772318.js


BIN
dist1/js/chunk-4b928543.1668695772318.js.gz


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/js/chunk-4c732b19.1668695772318.js


BIN
dist1/js/chunk-4c732b19.1668695772318.js.gz


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/js/chunk-5190983c.1668695772318.js


BIN
dist1/js/chunk-5190983c.1668695772318.js.gz


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/js/chunk-743c3027.1668695772318.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/js/chunk-c89bae56.1668695772318.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/js/chunk-ea83faca.1668695772318.js


BIN
dist1/js/chunk-ea83faca.1668695772318.js.gz


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist1/js/chunk-vendors.1668695772318.js


BIN
dist1/js/chunk-vendors.1668695772318.js.gz


BIN
dist1/logo.png


+ 1 - 0
dist1/version.json

@@ -0,0 +1 @@
+{"version":1668695784492}

+ 10 - 0
src/App.vue

@@ -16,6 +16,16 @@ export default {
       connection: null
     }
   },
+  watch: {
+		$route: {
+			handler (to, from) {
+        console.log(from.name)
+        if(from.name === 'store-in' || from.name === 'store-out') {
+          if(window.ws) window.ws.close()
+        }
+			}
+		}
+	},
   methods: {
     checkVersion () {
       axios.defaults.headers.get['Cache-Control'] = 'no-cache'

+ 1 - 1
src/components/my-modal-form/my-modal-material.vue

@@ -180,7 +180,7 @@ export default {
                   if (that.handleData[params.row._index].stockQty < that.handleData[params.row._index].quantity) {
                     that.$Message.error('输入数量不可大于实时库存')
                   }
-                  that.handleArea(params.row._index)
+                  //that.handleArea(params.row._index)
                 }
               }
             })

+ 2 - 2
src/components/my-nav.vue

@@ -117,11 +117,11 @@ name: "my-nav",
     this.timer = setInterval(() => {
       this.time = this.$dayjs().format('YYYY年MM月DD日 HH:mm:ss')
     }, 1000)
-    this.SRConnection()
+    //this.SRConnection()
   },
   destroyed() {
     clearInterval(this.timer)
-    this.connection.stop()
+    //this.connection.stop()
   }
 }
 </script>

+ 12 - 2
src/router/routers.js

@@ -14,12 +14,22 @@ const routes = [
   {
     path: '/store-in',
     name: 'store-in',
-    component: () => import('@/views/store-in.vue')
+    component: () => import('@/views/store-in-2.vue')
+  },
+  {
+    path: '/store-in-2',
+    name: 'store-in',
+    component: () => import('@/views/store-in-2.vue')
   },
   {
     path: '/store-out',
     name: 'store-out',
-    component: () => import('@/views/store-out.vue')
+    component: () => import('@/views/store-out-2.vue')
+  },
+  {
+    path: '/store-out-2',
+    name: 'store-out',
+    component: () => import('@/views/store-out-2.vue')
   },
   {
     path: '/store-out-list',

+ 2 - 2
src/views/Home.vue

@@ -15,10 +15,10 @@
         <img :src="outPic" alt="">
         <span class="label blue">出库</span>
       </div>
-      <div class="item" @click="go(2)">
+      <!-- <div class="item" @click="go(2)">
         <img :src="stock" alt="">
         <span class="label other">调仓</span>
-      </div>
+      </div> -->
     </div>
   </div>
 </template>

+ 191 - 57
src/views/store-change.vue

@@ -35,7 +35,7 @@
                   <div>物料名称:{{ item.materialName }}</div>
                 </div>
                 <div class="col" style="flex: 1"  :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
-                  <div>标签值:{{ item.rfidCode }}</div>
+                  <div>标签值:{{ item.rfid }}</div>
                 </div>
                 <div class="col" style="flex: 1"  :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
                   <div>数量:{{ item.quantity || 0 }}米</div>
@@ -54,7 +54,7 @@
             </div>
             <div style="height: calc(100% - 46px);overflow: auto">
               <div class="row"
-                   v-for="(item, index) in scanData.materialItems"
+                   v-for="(item, index) in materialItemsCopy"
                    :key="index">
                 <div class="col" style="flex: 3;" :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
                   <div>{{ item.materialName }}</div>
@@ -63,7 +63,7 @@
                   <div>调仓件数:{{ item.tagCount }}</div>
                 </div>
                 <div class="col" style="flex: 2" :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
-                  <div>调仓数量:{{ item.totalQuantity }}米</div>
+                  <div>调仓数量:{{ item.quantity }}米</div>
                 </div>
               </div>
             </div>
@@ -112,7 +112,6 @@
       </div>
     </div>
     <div v-else style="padding: 10px 0;color: #FFFFFF">暂无数据</div>
-
   </Modal>
 </div>
 </template>
@@ -136,10 +135,14 @@ export default {
       reading: false,
       connection: null,
       data: [], // 左侧数据列表
-      scanData: {}, // 扫描数据
+      scanData: {
+				rfidTagItems: [],
+				materialItems: [],
+			}, // 扫描数据
       otherData: [], // 扫描辅助数据
       tempDelData: [], // 临时删除列表
-      remark: ''
+      remark: '',
+      materialItemsCopy:[],
     }
   },
   components: {
@@ -147,25 +150,51 @@ export default {
   },
   methods: {
     /* 临时删除 */
-    del (item, index) {
-      if (item.isTemp) {
-        this.scanData.rfidTagItems.splice(index, 1)
-        this.scanData.materialItems.splice(index, 1)
-        /* 添加一个临时删除数据 用于再次扫描数据时过滤已临时删除的数据 */
-        this.tempDelData.push(item)
-      } else {
-        DelScanRfid({
-          rfid: item.rfidCode,
-          plcStationCode: sessionStorage.getItem('plcCode')
-        }).then(res => {
-          if (res.code === 0) {
-            this.$Message.info('删除成功!')
-            this.tempDelData.push(item)
-            this.getScanList()
-          }
-        })
-      }
-    },
+		del(item, index) {
+			// if (item.isTemp) {
+			this.scanData.rfidTagItems.splice(index, 1)
+			this.scanData.materialItems.splice(index, 1)
+			/* 添加一个临时删除数据 用于再次扫描数据时过滤已临时删除的数据 */
+			this.tempDelData.push(item)
+			this.materialItemsCopy = []
+			for (
+				let i = 0;
+				i < this.scanData.rfidTagItems.length;
+				i++
+			) {
+				const element = this.scanData.rfidTagItems[i]
+				
+				if (this.materialItemsCopy.length == 0) {
+					this.materialItemsCopy.push({
+						...element,
+						tagCount: 1,
+					})
+				} else {
+					var isTotal = false
+
+					for (
+						let j = 0;
+						j < this.materialItemsCopy.length;
+						j++
+					) {
+						const jelement = this.materialItemsCopy[j]
+						if (
+							element.materialCode ===
+							jelement.materialCode
+						) {
+							isTotal = true
+							jelement.tagCount++
+							jelement.quantity += element.quantity
+						}
+					}
+					if (!isTotal)
+						this.materialItemsCopy.push({
+							...element,
+							tagCount: 1,
+						})
+				}
+			}
+		},
     add (item) {
       item.totalQuantity = item.qty
       item.quantity = item.qty
@@ -203,13 +232,15 @@ export default {
     /* 是否通过 0否 1是 */
     pass(type) {
       if (type === 0) {
-        this.scanData.rfidTagItems = []
-        this.scanData.materialItems = []
-        ReScan({
-          reScanType:1,
-          storageType: sessionStorage.getItem('plcCode'),
-          storageDoor: sessionStorage.getItem('door')
-        })
+        this.$Message.info('请重新扫描入库!')
+				this.scanData.rfidTagItems = []
+				this.scanData.materialItems = []
+				this.materialItemsCopy = []
+				this.tempDelData = []
+				if(window.ws) window.ws.close()
+				setTimeout(() => {
+					this.socketInit()
+				}, 500);
       } else {
         if (!this.toPlcStationCode) {
           return this.$Message.error('请选择仓库')
@@ -226,30 +257,132 @@ export default {
         })
       }
     },
-    getScanList () {
-      GetScanRfidStocInOut({
-        storagePlcCode: sessionStorage.getItem('plcCode'),
-        stockInOutScanType: 0
-      }).then(scanRes => {
-        if (scanRes.code === 0) {
-          this.reading = false
-          this.scanData = scanRes.result
-          /* 临时删除的数据不可再添加到出入库列表中 */
-          this.tempDelData.forEach(temp => {
-            for (const index in this.scanData.rfidTagItems) {
-              if (temp.materialCode === this.scanData.rfidTagItems[index].materialCode) {
-                this.scanData.rfidTagItems.splice(index, 1)
-              }
-            }
-            for (const index in this.scanData.materialItems) {
-              if (temp.materialCode === this.scanData.materialItems[index].materialCode) {
-                this.scanData.materialItems.splice(index, 1)
-              }
-            }
-          })
-        }
-      })
-    },
+    unique(arr, val) {
+			const res = new Map()
+			return arr.filter(
+				(item) => !res.has(item[val]) && res.set(item[val], 1)
+			)
+		},
+    getScanList(rfidTagItems) {
+			if(!rfidTagItems) return
+			this.reading = false
+			console.log(rfidTagItems)
+			this.scanData.rfidTagItems = [
+				...this.scanData.rfidTagItems,
+				...rfidTagItems,
+			]
+			this.scanData.materialItems = [
+				...this.scanData.materialItems,
+			]
+			this.scanData.rfidTagItems = this.unique(
+				this.scanData.rfidTagItems,
+				'rfid'
+			)
+			/* 临时删除的数据不可再添加到出入库列表中 */
+			this.tempDelData.forEach((temp) => {
+				for (const index in this.scanData.rfidTagItems) {
+					if (
+						temp.rfid ===
+						this.scanData.rfidTagItems[index].rfid
+					) {
+						this.scanData.rfidTagItems.splice(index, 1)
+					}
+				}
+
+				for (const index in this.scanData.materialItems) {
+					if (
+						temp.materialCode ===
+						this.scanData.materialItems[index].materialCode
+					) {
+						this.scanData.materialItems.splice(index, 1)
+					}
+				}
+			})
+			this.materialItemsCopy = []
+			for (
+				let i = 0;
+				i < this.scanData.rfidTagItems.length;
+				i++
+			) {
+				const element = this.scanData.rfidTagItems[i]
+				
+				if (this.materialItemsCopy.length == 0) {
+					this.materialItemsCopy.push({
+						...element,
+						tagCount: 1,
+					})
+				} else {
+					var isTotal = false
+
+					for (
+						let j = 0;
+						j < this.materialItemsCopy.length;
+						j++
+					) {
+						const jelement = this.materialItemsCopy[j]
+						if (
+							element.materialCode ===
+							jelement.materialCode
+						) {
+							isTotal = true
+							jelement.tagCount++
+							jelement.quantity += element.quantity
+						}
+					}
+					if (!isTotal)
+						this.materialItemsCopy.push({
+							...element,
+							tagCount: 1,
+						})
+				}
+			}
+			
+			this.data.forEach((item) => {
+				this.scanData.rfidTagItems.forEach((scan) => {
+					if (item.rfid === scan.rfid) {
+						item.checked = true
+					}
+				})
+			})
+		},
+    socketInit() {
+			const v = this
+			window.ws = new WebSocket(
+				'ws://120.79.80.64:8050/cloudApi/webStock/' + window.localStorage.getItem('token')
+				//'ws://192.168.1.97:8300/webStock/' + window.localStorage.getItem('token')
+			)
+			//申请一个WebSocket对象,参数是服务端地址,同http协议使用http://开头一样,WebSocket协议的url使用ws://开头,另外安全的WebSocket协议使用wss://开头
+			window.ws.onopen = function () {
+				//当WebSocket创建成功时,触发onopen事件
+				console.log('open')
+				
+			}
+			window.ws.onmessage = function (e) {
+				//当客户端收到服务端发来的消息时,触发onmessage事件,参数e.data包含server传递过来的数据
+				
+				var msg = JSON.parse(e.data)
+				if (msg.type == 1) {
+					msg.data.instructions = 2
+					msg.data.businessType = 2
+					msg.data.stockHouseId = 'c185883dba22478cb593d33f6b66cc53',
+					msg.data.type = 2
+					msg.type = 2
+					window.ws.send(JSON.stringify(msg))
+				}
+				if(msg.type == 3){
+					console.log(msg.data.rfidData)
+					v.getScanList(msg.data.rfidData)
+				}
+			}
+			window.ws.onclose = function (e) {
+				//当客户端收到服务端发送的关闭连接请求时,触发onclose事件
+				console.log('close')
+			}
+			window.ws.onerror = function (e) {
+				//如果出现连接、处理、接收、发送数据失败的时候触发onerror事件
+				console.log(error)
+			}
+		},
     getStockHouse () {
       GetStockHouse().then(res => {
         if(res.code === 0) {
@@ -265,7 +398,8 @@ export default {
   },
   mounted() {
     this.tempDelData = []
-    this.getScanList()
+    //this.getScanList()
+    this.socketInit()
     this.getStockHouse()
     this.addTimer = setInterval(() => {
       this.percent += 1

+ 760 - 537
src/views/store-in - 副本 (2).vue

@@ -1,138 +1,285 @@
 <template>
-<div class="container">
-  <my-nav @listener-in="inHandle" @listener-helper="helperHandle"></my-nav>
-  <div class="content">
-    <div class="reading" v-if="reading">
-      入库扫描中<br/>
-      请将需要入库的物料推入感应门
-    </div>
-    <div v-else style="height: 100%">
-      <div style="display: flex;justify-content: space-between;align-items: center">
-        <div style="width: 108px"></div>
-        <div class="title">入库扫描</div>
-        <div style="padding: 0 10px">
-          <Button type="primary" @click="scanShow=true">辅助扫描</Button>
-        </div>
-      </div>
-      <div class="main">
-        <div class="list-wrap">
-          <div class="list" style="margin-right: 20px;">
-            <div class="sub-title">已贴标物料</div>
-            <div style="height: calc(100% - 46px);overflow: auto">
-              <div class="row" v-for="(item, index) in data" :key="index">
-                <div class="col" style="width: 50px;align-items: center;">
-                  <Icon type="ios-checkmark-circle" color="red" size="18" v-if="item.checked"/>
-                </div>
-                <div class="col" style="flex: 1">
-                  <div>{{ item.materialName }}</div>
-                  <div>物料长度:{{ item.quantity }}米</div>
-                </div>
-              </div>
-            </div>
-          </div>
-          <div class="list">
-            <div class="sub-title">本次入库</div>
-            <div style="height: calc(100% - 46px);overflow: auto">
-              <div class="row" v-for="(item, index) in scanData.rfidTagItems" :key="index">
-                <div class="col" style="width: 50px;align-items: center;"></div>
-                <div class="col" style="flex: 1"  :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
-                  <div>{{ item.materialName }}</div>
-                  <div>物料长度:{{ item.quantity || 0 }}米</div>
-                </div>
-                <div class="col" style="flex: 1"  :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
-                  <div>标签值:{{ item.rfidCode }}</div>
-                </div>
-                <div class="col" style="width: 50px;">
-                  <Icon type="ios-trash" size="20" color="red" @click="del(item, index)" style="cursor: pointer"/>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="list-wrap bottom">
-          <div class="list">
-            <div class="sub-title">
-              本次统计
-              <a class="remark" href="#" @click="show = true">填写备注</a>
-            </div>
-            <div style="height: calc(100% - 46px);overflow: auto">
-              <div class="row"
-                   v-for="(item, index) in materialItemsCopy"
-                   :key="index">
-                <div class="col" style="flex: 3;" :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
-                  <div>{{ item.materialName }}</div>
-                </div>
-                <div class="col" style="flex: 2" :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
-                  <div>入库件数:{{ item.tagCount }}</div>
-                </div>
-                <div class="col" style="flex: 2" :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
-                  <div>入库数量:{{ item.quantity }}米</div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-      <div class="footer">
-        <Button type="error" size="large" style="margin-right: 20px" @click="pass(0)">重新扫描</Button>
-        <Button type="success" size="large" @click="pass(1)">确认无误</Button>
-      </div>
-    </div>
-  </div>
-  <div class="remark-content">
-    <Modal
-        v-model="modal"
-        :mask-closable="false"
-        :closable="false"
-        :fullscreen="true"
-        :footer-hide="true"
-        >
-      <Progress :percent="percent" :stroke-color="['#108ee9', '#87d068']" :hide-info="true" style="width: 400px"/>
-    </Modal>
-  </div>
-  <!-- 填写备注 -->
-  <Modal
-      v-model="show"
-      :closable="false"
-      :footer-hide="true"
-      class-name="vertical-center-modal"
-      @on-cancel="cancel"
-     >
-    <div class="remark-content">
-      <div class="title">填写备注</div>
-      <Input v-model="remark" type="textarea" :rows="10"/>
-      <div class="btn">
-        <Button @click="cfm" type="success" style="width: 120px">确定</Button>
-      </div>
-    </div>
-  </Modal>
-  <!-- 辅助扫描 -->
-  <Modal
-      v-model="scanShow"
-      class-name="vertical-center-modal"
-      @on-cancel="cancel"
-  >
-    <div class="scan-title" slot="header">辅助扫描</div>
-    <div class="scan-btn" slot="footer">
-      <Button type="primary" style="width: 80px" @click="scanShow = false">关闭</Button>
-    </div>
-    <div class="scan-content" v-if="otherData.length > 0">
-      <div class="item" v-for="(item, index) in otherData" :key="index">
-        <div class="left">
-          <div class="row">RFID标签:{{ item.rfidCode }}</div>
-          <div class="row">物料编码:{{ item.materialCode }}</div>
-          <div class="row">物料名称:{{ item.materialName }}</div>
-          <div class="row">最近操作:{{ item.lastOpera }}</div>
-        </div>
-        <div class="right">
-          <Button type="primary" ghost @click="add(item)" v-if="item.lastOpera.indexOf('入库') === -1">入库</Button>
-        </div>
-      </div>
-    </div>
-    <div v-else style="padding: 10px 0;color: #FFFFFF">暂无数据</div>
-
-  </Modal>
-</div>
+	<div class="container">
+		<my-nav
+			@listener-in="inHandle"
+			@listener-helper="helperHandle"
+		></my-nav>
+		<div class="content">
+			<div class="reading" v-if="reading">
+				入库扫描中<br />
+				请将需要入库的物料推入感应门
+			</div>
+			<div v-else style="height: 100%">
+				<div
+					style="
+						display: flex;
+						justify-content: space-between;
+						align-items: center;
+					"
+				>
+					<div style="width: 108px"></div>
+					<div class="title">入库扫描</div>
+					<div style="padding: 0 10px">
+						<Button type="primary" @click="scanShow = true"
+							>辅助扫描</Button
+						>
+					</div>
+				</div>
+				<div class="main">
+					<div class="list-wrap">
+						<div class="list" style="margin-right: 20px">
+							<div class="sub-title">已贴标物料</div>
+							<div
+								style="
+									height: calc(100% - 46px);
+									overflow: auto;
+								"
+							>
+								<div
+									class="row"
+									v-for="(item, index) in data"
+									:key="index"
+								>
+									<div
+										class="col"
+										style="width: 50px; align-items: center"
+									>
+										<Icon
+											type="ios-checkmark-circle"
+											color="red"
+											size="18"
+											v-if="item.checked"
+										/>
+									</div>
+									<div class="col" style="flex: 1">
+										<div>{{ item.materialName }}</div>
+										<div>
+											物料长度:{{ item.quantity }}米
+										</div>
+									</div>
+								</div>
+							</div>
+						</div>
+						<div class="list">
+							<div class="sub-title">本次入库</div>
+							<div
+								style="
+									height: calc(100% - 46px);
+									overflow: auto;
+								"
+							>
+								<div
+									class="row"
+									v-for="(
+										item, index
+									) in scanData.rfidTagItems"
+									:key="index"
+								>
+									<div
+										class="col"
+										style="width: 50px; align-items: center"
+									></div>
+									<div
+										class="col"
+										style="flex: 1"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>{{ item.materialName }}</div>
+										<div>
+											物料长度:{{ item.quantity || 0 }}米
+										</div>
+									</div>
+									<div
+										class="col"
+										style="flex: 1"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>标签值:{{ item.rfidCode }}</div>
+									</div>
+									<div class="col" style="width: 50px">
+										<Icon
+											type="ios-trash"
+											size="20"
+											color="red"
+											@click="del(item, index)"
+											style="cursor: pointer"
+										/>
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+					<div class="list-wrap bottom">
+						<div class="list">
+							<div class="sub-title">
+								本次统计
+								<a class="remark" href="#" @click="show = true"
+									>填写备注</a
+								>
+							</div>
+							<div
+								style="
+									height: calc(100% - 46px);
+									overflow: auto;
+								"
+							>
+								<div
+									class="row"
+									v-for="(item, index) in materialItemsCopy"
+									:key="index"
+								>
+									<div
+										class="col"
+										style="flex: 3"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>{{ item.materialName }}</div>
+									</div>
+									<div
+										class="col"
+										style="flex: 2"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>入库件数:{{ item.tagCount }}</div>
+									</div>
+									<div
+										class="col"
+										style="flex: 2"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>
+											入库数量:{{ item.quantity }}米
+										</div>
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="footer">
+					<Button
+						type="error"
+						size="large"
+						style="margin-right: 20px"
+						@click="pass(0)"
+						>重新扫描</Button
+					>
+					<Button type="success" size="large" @click="pass(1)"
+						>确认无误</Button
+					>
+				</div>
+			</div>
+		</div>
+		<div class="remark-content">
+			<Modal
+				v-model="modal"
+				:mask-closable="false"
+				:closable="false"
+				:fullscreen="true"
+				:footer-hide="true"
+			>
+				<Progress
+					:percent="percent"
+					:stroke-color="['#108ee9', '#87d068']"
+					:hide-info="true"
+					style="width: 400px"
+				/>
+			</Modal>
+		</div>
+		<!-- 填写备注 -->
+		<Modal
+			v-model="show"
+			:closable="false"
+			:footer-hide="true"
+			class-name="vertical-center-modal"
+			@on-cancel="cancel"
+		>
+			<div class="remark-content">
+				<div class="title">填写备注</div>
+				<Input v-model="remark" type="textarea" :rows="10" />
+				<div class="btn">
+					<Button @click="cfm" type="success" style="width: 120px"
+						>确定</Button
+					>
+				</div>
+			</div>
+		</Modal>
+		<!-- 辅助扫描 -->
+		<Modal
+			v-model="scanShow"
+			class-name="vertical-center-modal"
+			@on-cancel="cancel"
+		>
+			<div class="scan-title" slot="header">辅助扫描</div>
+			<div class="scan-btn" slot="footer">
+				<Button
+					type="primary"
+					style="width: 80px"
+					@click="scanShow = false"
+					>关闭</Button
+				>
+			</div>
+			<div class="scan-content" v-if="otherData.length > 0">
+				<div
+					class="item"
+					v-for="(item, index) in otherData"
+					:key="index"
+				>
+					<div class="left">
+						<div class="row">RFID标签:{{ item.rfidCode }}</div>
+						<div class="row">物料编码:{{ item.materialCode }}</div>
+						<div class="row">物料名称:{{ item.materialName }}</div>
+						<div class="row">最近操作:{{ item.lastOpera }}</div>
+					</div>
+					<div class="right">
+						<Button
+							type="primary"
+							ghost
+							@click="add(item)"
+							v-if="item.lastOpera.indexOf('入库') === -1"
+							>入库</Button
+						>
+					</div>
+				</div>
+			</div>
+			<div v-else style="padding: 10px 0; color: #ffffff">暂无数据</div>
+		</Modal>
+	</div>
 </template>
 
 <script>
@@ -140,421 +287,497 @@ import MyNav from '@/components/my-nav'
 import * as signalR from '@microsoft/signalr'
 import { MessagePackHubProtocol } from '@microsoft/signalr-protocol-msgpack'
 import withUrl from '@/config/withUrl'
-import {GetHasTagMaterialList, PlcStorageIn, ReScan, GetScanRfidStocInOut, DelScanRfid} from '@/api/integrated'
-import store from "@/store";
-import {logOut} from "@/libs/util";
+import {
+	GetHasTagMaterialList,
+	PlcStorageIn,
+	ReScan,
+	GetScanRfidStocInOut,
+	DelScanRfid,
+} from '@/api/integrated'
+import store from '@/store'
+import { logOut } from '@/libs/util'
 export default {
-  name: "store-in",
-  data() {
-    return {
-      scanShow: false,
-      show: false,
-      modal: false,
-      percent: 0,
-      addTimer: null,
-      overTimer: null,
-      reading: false,
-      connection: null,
-      data: [], // 左侧数据列表
-      scanData: {}, // 扫描数据
-      otherData: [], // 扫描辅助数据
-      tempDelData: [], // 临时删除列表
-      remark: '',
-      materialItemsCopy:[],
-    }
-  },
-  components: {
-    MyNav
-  },
-  methods: {
-    add (item) {
-      item.totalQuantity = item.qty
-      item.quantity = item.qty
-      // 辅助扫描的添加一个isTemp 标识以供删除区分
-      if (this.scanData.rfidTagItems.find(scan => scan.materialCode === item.materialCode)) {
-        this.$Message.error('物料已添加')
-      } else {
-        this.scanData.rfidTagItems.push({...item, isTemp: true})
-        this.scanData.materialItems.push({...item, isTemp: true})
-        this.$Message.info('添加成功')
-      }
-    },
-    cancel () {
-      this.remark = ''
-    },
-    cfm () {
-      this.show = false
-    },
-    /* 临时删除 */
-    del (item, index) {
-      if (item.isTemp) {
-        this.scanData.rfidTagItems.splice(index, 1)
-        this.scanData.materialItems.splice(index, 1)
-        /* 添加一个临时删除数据 用于再次扫描数据时过滤已临时删除的数据 */
-        this.tempDelData.push(item)
-      } else {
-        DelScanRfid({
-          rfid: item.rfidCode,
-          plcStationCode: sessionStorage.getItem('plcCode')
-        }).then(res => {
-          if (res.code === 0) {
-            this.$Message.info('删除成功!')
-            this.tempDelData.push(item)
-            this.getScanList()
-          }
-        })
-      }
-    },
-    /* 辅助扫描通知 */
-    helperHandle (data) {
-      this.otherData = data
-    },
-    /* 入库通知 */
-    inHandle() {
-      this.getScanList()
-      clearTimeout(this.overTimer)
-      this.overTimer = setTimeout(() => {
-        clearInterval(this.addTimer)
-        this.percent = 100
-        setTimeout(() => {
-          this.modal = false
-        }, 500)
-      }, 3000)
-    },
-    /* 是否通过 0否 1是 */
-    pass(type) {
-      if (type === 0) {
-        this.$Message.info('请重新扫描入库!')
-        this.scanData.rfidTagItems = []
-        this.scanData.materialItems = []
-        this.materialItemsCopy = []
-        ReScan({
-          reScanType: 0,
-          storageType: sessionStorage.getItem('plcCode'),
-          storageDoor: sessionStorage.getItem('door')
-        })
-      } else if (type === 1) {
-        // 入库
-        PlcStorageIn({
-          storageDoor: sessionStorage.getItem('door'),
-          plcStationCode: sessionStorage.getItem('plcCode'),
-          rfidList: this.scanData.rfidTagItems.map(item => item.rfidCode),
-          remark: this.remark
-        }).then(res => {
-          if (res.code === 0) {
-            this.$Message.info('入库成功!')
-            logOut()
-            // this.$store.commit('setHasGetInfo', false)
-            // this.$store.commit('setToken', '')
-            // setTimeout(() => {
-            //   this.$router.push({
-            //     name: 'Home',
-            //     query: {
-            //       plcCode: sessionStorage.getItem('plcCode'),
-            //       door: sessionStorage.getItem('door')
-            //     }
-            //   })
-            // }, 500)
-          }
-        })
-      }
-    },
-    getList() {
-      /* 获取已贴标数据 */
-      GetHasTagMaterialList().then(res => {
-        if (res.code === 0) {
-          this.data = res.result
-        }
-      })
-    },
-    unique(arr, val) {
-      const res = new Map()
-      return arr.filter((item) => !res.has(item[val]) && res.set(item[val], 1))
-    },
-    getScanList () {
-      GetScanRfidStocInOut({
-        storagePlcCode: sessionStorage.getItem('plcCode'),
-        stockInOutScanType: 0
-      }).then(scanRes => {
-        if (scanRes.code === 0) {
-          this.reading = false
-          this.scanData = scanRes.result
-          /* 临时删除的数据不可再添加到出入库列表中 */
-          this.tempDelData.forEach(temp => {
+	name: 'store-in',
+	data() {
+		return {
+			scanShow: false,
+			show: false,
+			modal: false,
+			percent: 0,
+			addTimer: null,
+			overTimer: null,
+			reading: false,
+			connection: null,
+			data: [], // 左侧数据列表
+			scanData: {}, // 扫描数据
+			otherData: [], // 扫描辅助数据
+			tempDelData: [], // 临时删除列表
+			remark: '',
+			materialItemsCopy: [],
+			a: {
+				// 创建时间
+				createTime: 1667287040055,
+
+				data: {
+					// 指令(开启rfid扫描时传入)
+					instructions: 'test',
+
+					// 操作类型 2开启rfid扫描 9关闭读写器,停止扫描rfid
+					type: '2',
+
+					// 业务类型:1出库 2入库
+					businessType: 1,
 
-            for (const index in this.scanData.rfidTagItems) {
-              
-              if (temp.materialCode === this.scanData.rfidTagItems[index].materialCode) {
-                this.scanData.rfidTagItems.splice(index, 1)
-              }
-            }
-            for (const index in this.scanData.materialItems) {
-              if (temp.materialCode === this.scanData.materialItems[index].materialCode) {
-                this.scanData.materialItems.splice(index, 1)
-              }
-            }
-          })
-          this.materialItemsCopy = []
-					for (let i = 0; i < this.scanData.rfidTagItems.length; i++) {
-						const element = this.scanData.rfidTagItems[i];
-						console.log(this.materialItemsCopy,12312312)
-						if(this.materialItemsCopy.length == 0){
-							this.materialItemsCopy.push({...element,tagCount:1})
-						}else{
+					// 仓库id: 一楼仓库'c185883dba22478cb593d33f6b66cc53' 四楼仓库'0b8f584250bb4b40b72d641ce4849d15'
+					stockHouseId: 'c185883dba22478cb593d33f6b66cc53',
+
+					// 推送rfid返回结果
+					rfidData: [
+						{
+							// 物料id
+							materialId: '',
+							// 物料编码
+							materialCode: '',
+							// 物料名称
+							materialName: '',
+							// 数量
+							quantity: '',
+							// rfid
+							rfid: '',
+						},
+					],
+				},
+				// 本次长连接id
+				sessionId: 'n6YAoMiXOAJThqR0km24F5sX1eisFZ8-cKwJwt7c',
+
+				// 长连接类型 1初始化返回 2操作上位机 3推送rfid
+				type: 2,
+
+				userId: '10',
+			},
+		}
+	},
+	components: {
+		MyNav,
+	},
+	methods: {
+		add(item) {
+			item.totalQuantity = item.qty
+			item.quantity = item.qty
+			// 辅助扫描的添加一个isTemp 标识以供删除区分
+			if (
+				this.scanData.rfidTagItems.find(
+					(scan) => scan.materialCode === item.materialCode
+				)
+			) {
+				this.$Message.error('物料已添加')
+			} else {
+				this.scanData.rfidTagItems.push({ ...item, isTemp: true })
+				this.scanData.materialItems.push({ ...item, isTemp: true })
+				this.$Message.info('添加成功')
+			}
+		},
+		cancel() {
+			this.remark = ''
+		},
+		cfm() {
+			this.show = false
+		},
+		/* 临时删除 */
+		del(item, index) {
+			if (item.isTemp) {
+				this.scanData.rfidTagItems.splice(index, 1)
+				this.scanData.materialItems.splice(index, 1)
+				/* 添加一个临时删除数据 用于再次扫描数据时过滤已临时删除的数据 */
+				this.tempDelData.push(item)
+			} else {
+				DelScanRfid({
+					rfid: item.rfidCode,
+					plcStationCode: sessionStorage.getItem('plcCode'),
+				}).then((res) => {
+					if (res.code === 0) {
+						this.$Message.info('删除成功!')
+						this.tempDelData.push(item)
+						this.getScanList()
+					}
+				})
+			}
+		},
+		/* 辅助扫描通知 */
+		helperHandle(data) {
+			this.otherData = data
+		},
+		/* 入库通知 */
+		inHandle() {
+			this.getScanList()
+			clearTimeout(this.overTimer)
+			this.overTimer = setTimeout(() => {
+				clearInterval(this.addTimer)
+				this.percent = 100
+				setTimeout(() => {
+					this.modal = false
+				}, 500)
+			}, 3000)
+		},
+		/* 是否通过 0否 1是 */
+		pass(type) {
+			if (type === 0) {
+				this.$Message.info('请重新扫描入库!')
+				this.scanData.rfidTagItems = []
+				this.scanData.materialItems = []
+				this.materialItemsCopy = []
+				ReScan({
+					reScanType: 0,
+					storageType: sessionStorage.getItem('plcCode'),
+					storageDoor: sessionStorage.getItem('door'),
+				})
+			} else if (type === 1) {
+				// 入库
+				PlcStorageIn({
+					storageDoor: sessionStorage.getItem('door'),
+					plcStationCode: sessionStorage.getItem('plcCode'),
+					rfidList: this.scanData.rfidTagItems.map(
+						(item) => item.rfidCode
+					),
+					remark: this.remark,
+				}).then((res) => {
+					if (res.code === 0) {
+						this.$Message.info('入库成功!')
+						logOut()
+						// this.$store.commit('setHasGetInfo', false)
+						// this.$store.commit('setToken', '')
+						// setTimeout(() => {
+						//   this.$router.push({
+						//     name: 'Home',
+						//     query: {
+						//       plcCode: sessionStorage.getItem('plcCode'),
+						//       door: sessionStorage.getItem('door')
+						//     }
+						//   })
+						// }, 500)
+					}
+				})
+			}
+		},
+		getList() {
+			/* 获取已贴标数据 */
+			GetHasTagMaterialList().then((res) => {
+				if (res.code === 0) {
+					this.data = res.result
+				}
+			})
+		},
+		unique(arr, val) {
+			const res = new Map()
+			return arr.filter(
+				(item) => !res.has(item[val]) && res.set(item[val], 1)
+			)
+		},
+		getScanList() {
+			GetScanRfidStocInOut({
+				storagePlcCode: sessionStorage.getItem('plcCode'),
+				stockInOutScanType: 0,
+			}).then((scanRes) => {
+				if (scanRes.code === 0) {
+					this.reading = false
+					this.scanData = scanRes.result
+					/* 临时删除的数据不可再添加到出入库列表中 */
+					this.tempDelData.forEach((temp) => {
+						for (const index in this.scanData.rfidTagItems) {
+							if (
+								temp.materialCode ===
+								this.scanData.rfidTagItems[index].materialCode
+							) {
+								this.scanData.rfidTagItems.splice(index, 1)
+							}
+						}
+						for (const index in this.scanData.materialItems) {
+							if (
+								temp.materialCode ===
+								this.scanData.materialItems[index].materialCode
+							) {
+								this.scanData.materialItems.splice(index, 1)
+							}
+						}
+					})
+					this.materialItemsCopy = []
+					for (
+						let i = 0;
+						i < this.scanData.rfidTagItems.length;
+						i++
+					) {
+						const element = this.scanData.rfidTagItems[i]
+						console.log(this.materialItemsCopy, 12312312)
+						if (this.materialItemsCopy.length == 0) {
+							this.materialItemsCopy.push({
+								...element,
+								tagCount: 1,
+							})
+						} else {
 							var isTotal = false
-							
-							for (let j = 0; j < this.materialItemsCopy.length; j++) {
-								const jelement = this.materialItemsCopy[j];
-								if(element.materialCode === jelement.materialCode){
+
+							for (
+								let j = 0;
+								j < this.materialItemsCopy.length;
+								j++
+							) {
+								const jelement = this.materialItemsCopy[j]
+								if (
+									element.materialCode ===
+									jelement.materialCode
+								) {
 									isTotal = true
 									jelement.tagCount++
 									jelement.quantity += element.quantity
-									
 								}
 							}
-							if(!isTotal) this.materialItemsCopy.push({...element,tagCount:1})
+							if (!isTotal)
+								this.materialItemsCopy.push({
+									...element,
+									tagCount: 1,
+								})
 						}
-						
 					}
-          this.data.forEach(item => {
-            this.scanData.rfidTagItems.forEach(scan => {
-              if (item.rfidCode === scan.rfidCode) {
-                item.checked = true
-              }
-            })
-          })
-        }
-      })
-    }
-  },
-  mounted() {
-    this.tempDelData = []
-    this.getList()
-    this.getScanList()
-    this.addTimer = setInterval(() => {
-      this.percent += 1
-      if (this.percent === 100) {
-        clearInterval(this.addTimer)
-        clearTimeout(this.overTimer)
-        this.modal = false
-      }
-    }, 100)
-    this.overTimer = setTimeout(() => {
-      clearInterval(this.addTimer)
-      this.percent = 100
-      setTimeout(() => {
-        this.modal = false
-      }, 500)
-    }, 3000)
-  },
-  destroyed() {
-  }
+					this.data.forEach((item) => {
+						this.scanData.rfidTagItems.forEach((scan) => {
+							if (item.rfidCode === scan.rfidCode) {
+								item.checked = true
+							}
+						})
+					})
+				}
+			})
+		},
+	},
+	mounted() {
+		this.tempDelData = []
+		this.getList()
+		this.getScanList()
+		this.addTimer = setInterval(() => {
+			this.percent += 1
+			if (this.percent === 100) {
+				clearInterval(this.addTimer)
+				clearTimeout(this.overTimer)
+				this.modal = false
+			}
+		}, 100)
+		this.overTimer = setTimeout(() => {
+			clearInterval(this.addTimer)
+			this.percent = 100
+			setTimeout(() => {
+				this.modal = false
+			}, 500)
+		}, 3000)
+	},
+	destroyed() {},
 }
 </script>
 
 <style lang="scss" scoped>
-  .container {
-    width: 100vw;
-    height: 100vh;
-    overflow: auto;
-    //background: rgba(2, 125, 180, 1);
-    background-image: linear-gradient(270deg,
-        #2c3034 0%,
-        #50575e 49%,
-        #2c3034 100%);
-    .content {
-      margin: 10px;
-      height: calc(100% - 121.6px);
-      overflow: hidden;
-      box-sizing: border-box;
-      //background: rgba(1, 84, 120, 1);
-      border-radius: 10px;
-      .reading {
-        height: 100%;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        font-size: 36px;
-        font-weight: bold;
-        color: #00FFFF;
-      }
-      .title {
-        padding-bottom: 10px;
-        text-align: center;
-        font-size: 36px;
-        font-weight: bold;
-        color: #2dc57c;
-      }
-      .main {
-        height: calc(100% - 113.6px);
-        display: flex;
-        flex-direction: column;
-        .list-wrap {
-          flex: 2;
-          overflow: hidden;
-          padding: 0 10px;
-          width: 100%;
-          display: flex;
-          justify-content: space-between;
-          align-items: center;
-          .list {
-            position: relative;
-            //padding: 0 10px;
-            flex: 1;
-            height: 100%;
-            overflow: hidden;
-            //background: rgba(2, 125, 180, 0.486274509803922);
-            background: #2c3034;
-            border-radius: 4px;
-            border: solid 1px #3879e7;
-            .sub-title {
-              position: relative;
-              padding: 5px 0;
-              font-size: 24px;
-              color: #0077ff;
-              font-weight: bold;
-              .remark {
-                position: absolute;
-                right: 10px;
-                top: 50%;
-                transform: translateY(-50%);
-                font-size: 16px;
-                font-weight: normal;
-                color: #0077ff;
-              }
-            }
-            .row {
-              padding: 5px 0;
-              display: flex;
-              justify-content: space-between;
-              align-items: center;
-              //background: rgba(2, 167, 240, 1);
-              border-top: 1px solid #2655ad;
-              //border-radius: 5px;
-              &:last-child {
-                border-bottom: 1px solid #2655ad;
-              }
-              .col {
-                padding: 0 5px;
-                display: flex;
-                flex-direction: column;
-                align-items: flex-start;
-                justify-content: center;
-                text-align: left;
-                color: #ffffff;
-              }
-            }
-            .total {
-              padding: 5px 10px;
-              //position: absolute;
-              left: 0;
-              bottom: 0;
-              text-align: left;
-              font-size: 20px;
-              font-weight: bold;
-              color: #F59A23;
-              .top {
-                font-size: 24px;
-              }
-              .label {
-                margin-left: 40px  ;
-                display: inline-block;
-                width: 100px;
-              }
-            }
-          }
-        }
-        .bottom {
-          margin-top: 20px;
-          flex: 1;
-          .row {
-            border: none !important;
-          }
-          .col {
-            padding: 0 20px !important;
-          }
-        }
-      }
-      .footer {
-        padding: 10px 0;
-        padding-bottom: 0;
-        /deep/ .ivu-btn-large {
-          border-radius: 20px;
-          font-weight: bold;
-          width: 150px;
-        }
-      }
-    }
-  }
-  /deep/.ivu-modal-content {
-    background: #2c3034;
-  }
-  /deep/.ivu-modal-body {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    padding: 0;
-  }
-  /deep/.remark-content {
-    padding: 16px;
-    width: 100%;
-    .title {
-      font-size: 24px;
-      font-weight: bold;
-      text-align: center;
-      color: #FFFFFF;
-      padding-bottom: 10px;
-    }
-    .btn {
-      text-align: center;
-      padding-top: 10px;
-    }
-  }
-  /deep/ .ivu-modal-header {
-    border-bottom: none;
-  }
-  /deep/ .ivu-modal-footer {
-    border-top: none;
-  }
-  .scan-title {
-    font-size: 18px;
-    font-weight: bold;
-    color: #FFFFFF;
-  }
-  .scan-btn {
-    text-align: center;
-  }
-  .scan-content {
-    padding: 10px 16px;
-    width: 100%;
-    max-height: 40vh;
-    overflow: auto;
-    background-color: #3D3D3D;
-    color: #FFFFFF;
-    .item {
-      margin-bottom: 5px;
-      border-bottom: 1px solid #FFFFFF;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      &:last-child {
-        margin-bottom: 0;
-        border-bottom: none;
-      }
-      .left {
-        flex: 1;
-        overflow: hidden;
-      }
-      .right {
-        width: 60px;
-        /deep/ .ivu-btn-primary {
-          background-color: rgb(204, 228, 255);
-        }
-      }
-      .row {
-        margin-bottom: 5px;
-        word-break: break-all;
-      }
-    }
-  }
+.container {
+	width: 100vw;
+	height: 100vh;
+	overflow: auto;
+	//background: rgba(2, 125, 180, 1);
+	background-image: linear-gradient(
+		270deg,
+		#2c3034 0%,
+		#50575e 49%,
+		#2c3034 100%
+	);
+	.content {
+		margin: 10px;
+		height: calc(100% - 121.6px);
+		overflow: hidden;
+		box-sizing: border-box;
+		//background: rgba(1, 84, 120, 1);
+		border-radius: 10px;
+		.reading {
+			height: 100%;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			font-size: 36px;
+			font-weight: bold;
+			color: #00ffff;
+		}
+		.title {
+			padding-bottom: 10px;
+			text-align: center;
+			font-size: 36px;
+			font-weight: bold;
+			color: #2dc57c;
+		}
+		.main {
+			height: calc(100% - 113.6px);
+			display: flex;
+			flex-direction: column;
+			.list-wrap {
+				flex: 2;
+				overflow: hidden;
+				padding: 0 10px;
+				width: 100%;
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				.list {
+					position: relative;
+					//padding: 0 10px;
+					flex: 1;
+					height: 100%;
+					overflow: hidden;
+					//background: rgba(2, 125, 180, 0.486274509803922);
+					background: #2c3034;
+					border-radius: 4px;
+					border: solid 1px #3879e7;
+					.sub-title {
+						position: relative;
+						padding: 5px 0;
+						font-size: 24px;
+						color: #0077ff;
+						font-weight: bold;
+						.remark {
+							position: absolute;
+							right: 10px;
+							top: 50%;
+							transform: translateY(-50%);
+							font-size: 16px;
+							font-weight: normal;
+							color: #0077ff;
+						}
+					}
+					.row {
+						padding: 5px 0;
+						display: flex;
+						justify-content: space-between;
+						align-items: center;
+						//background: rgba(2, 167, 240, 1);
+						border-top: 1px solid #2655ad;
+						//border-radius: 5px;
+						&:last-child {
+							border-bottom: 1px solid #2655ad;
+						}
+						.col {
+							padding: 0 5px;
+							display: flex;
+							flex-direction: column;
+							align-items: flex-start;
+							justify-content: center;
+							text-align: left;
+							color: #ffffff;
+						}
+					}
+					.total {
+						padding: 5px 10px;
+						//position: absolute;
+						left: 0;
+						bottom: 0;
+						text-align: left;
+						font-size: 20px;
+						font-weight: bold;
+						color: #f59a23;
+						.top {
+							font-size: 24px;
+						}
+						.label {
+							margin-left: 40px;
+							display: inline-block;
+							width: 100px;
+						}
+					}
+				}
+			}
+			.bottom {
+				margin-top: 20px;
+				flex: 1;
+				.row {
+					border: none !important;
+				}
+				.col {
+					padding: 0 20px !important;
+				}
+			}
+		}
+		.footer {
+			padding: 10px 0;
+			padding-bottom: 0;
+			/deep/ .ivu-btn-large {
+				border-radius: 20px;
+				font-weight: bold;
+				width: 150px;
+			}
+		}
+	}
+}
+/deep/.ivu-modal-content {
+	background: #2c3034;
+}
+/deep/.ivu-modal-body {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	padding: 0;
+}
+/deep/.remark-content {
+	padding: 16px;
+	width: 100%;
+	.title {
+		font-size: 24px;
+		font-weight: bold;
+		text-align: center;
+		color: #ffffff;
+		padding-bottom: 10px;
+	}
+	.btn {
+		text-align: center;
+		padding-top: 10px;
+	}
+}
+/deep/ .ivu-modal-header {
+	border-bottom: none;
+}
+/deep/ .ivu-modal-footer {
+	border-top: none;
+}
+.scan-title {
+	font-size: 18px;
+	font-weight: bold;
+	color: #ffffff;
+}
+.scan-btn {
+	text-align: center;
+}
+.scan-content {
+	padding: 10px 16px;
+	width: 100%;
+	max-height: 40vh;
+	overflow: auto;
+	background-color: #3d3d3d;
+	color: #ffffff;
+	.item {
+		margin-bottom: 5px;
+		border-bottom: 1px solid #ffffff;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		&:last-child {
+			margin-bottom: 0;
+			border-bottom: none;
+		}
+		.left {
+			flex: 1;
+			overflow: hidden;
+		}
+		.right {
+			width: 60px;
+			/deep/ .ivu-btn-primary {
+				background-color: rgb(204, 228, 255);
+			}
+		}
+		.row {
+			margin-bottom: 5px;
+			word-break: break-all;
+		}
+	}
+}
 </style>

+ 0 - 534
src/views/store-in - 副本.vue

@@ -1,534 +0,0 @@
-<template>
-  <div class="container">
-    <my-nav @listener-in="inHandle" @listener-helper="helperHandle"></my-nav>
-    <div class="content">
-      <div class="reading" v-if="reading">
-        入库扫描中<br/>
-        请将需要入库的物料推入感应门
-      </div>
-      <div v-else style="height: 100%">
-        <div style="display: flex;justify-content: space-between;align-items: center">
-          <div style="width: 108px"></div>
-          <div class="title">入库扫描</div>
-          <div style="padding: 0 10px">
-            <Button type="primary" @click="scanShow=true">辅助扫描</Button>
-          </div>
-        </div>
-        <div class="main">
-          <div class="list-wrap">
-            <div class="list" style="margin-right: 20px;">
-              <div class="sub-title">已贴标物料</div>
-              <div style="height: calc(100% - 46px);overflow: auto">
-                <div class="row" v-for="(item, index) in data" :key="index">
-                  <div class="col" style="width: 50px;align-items: center;">
-                    <Icon type="ios-checkmark-circle" color="red" size="18" v-if="item.checked"/>
-                  </div>
-                  <div class="col" style="flex: 1">
-                    <div>{{ item.materialName }}</div>
-                    <div>物料长度:{{ item.quantity }}米</div>
-                  </div>
-                </div>
-              </div>
-            </div>
-            <div class="list">
-              <div class="sub-title">本次入库</div>
-              <div style="height: calc(100% - 46px);overflow: auto">
-                <div class="row" v-for="(item, index) in scanData.rfidTagItems" :key="index">
-                  <div class="col" style="width: 50px;align-items: center;"></div>
-                  <div class="col" style="flex: 1"  :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
-                    <div>{{ item.materialName }}</div>
-                    <div>物料长度:{{ item.quantity || 0 }}米</div>
-                  </div>
-                  <div class="col" style="flex: 1"  :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
-                    <div>标签值:{{ item.rfidCode }}</div>
-                  </div>
-                  <div class="col" style="width: 50px;">
-                    <Icon type="ios-trash" size="20" color="red" @click="del(item, index)" style="cursor: pointer"/>
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-          <div class="list-wrap bottom">
-            <div class="list">
-              <div class="sub-title">
-                本次统计
-                <a class="remark" href="#" @click="show = true">填写备注</a>
-              </div>
-              <div style="height: calc(100% - 46px);overflow: auto">
-                <div class="row"
-                     v-for="(item, index) in scanData.materialItems"
-                     :key="index">
-                  <div class="col" style="flex: 3;" :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
-                    <div>{{ item.materialName }}</div>
-                  </div>
-                  <div class="col" style="flex: 2" :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
-                    <div>入库件数:{{ item.tagCount }}</div>
-                  </div>
-                  <div class="col" style="flex: 2" :style="{ color: item.scanRfidStatus === 1 ? 'orange' : item.scanRfidStatus === 2? 'red': '#fff'}">
-                    <div>入库数量:{{ item.totalQuantity }}米</div>
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="footer">
-          <Button type="error" size="large" style="margin-right: 20px" @click="pass(0)">重新扫描</Button>
-          <Button type="success" size="large" @click="pass(1)">确认无误</Button>
-        </div>
-      </div>
-    </div>
-    <div class="remark-content">
-      <Modal
-          v-model="modal"
-          :mask-closable="false"
-          :closable="false"
-          :fullscreen="true"
-          :footer-hide="true"
-          >
-        <Progress :percent="percent" :stroke-color="['#108ee9', '#87d068']" :hide-info="true" style="width: 400px"/>
-      </Modal>
-    </div>
-    <!-- 填写备注 -->
-    <Modal
-        v-model="show"
-        :closable="false"
-        :footer-hide="true"
-        class-name="vertical-center-modal"
-        @on-cancel="cancel"
-       >
-      <div class="remark-content">
-        <div class="title">填写备注</div>
-        <Input v-model="remark" type="textarea" :rows="10"/>
-        <div class="btn">
-          <Button @click="cfm" type="success" style="width: 120px">确定</Button>
-        </div>
-      </div>
-    </Modal>
-    <!-- 辅助扫描 -->
-    <Modal
-        v-model="scanShow"
-        class-name="vertical-center-modal"
-        @on-cancel="cancel"
-    >
-      <div class="scan-title" slot="header">辅助扫描</div>
-      <div class="scan-btn" slot="footer">
-        <Button type="primary" style="width: 80px" @click="scanShow = false">关闭</Button>
-      </div>
-      <div class="scan-content" v-if="otherData.length > 0">
-        <div class="item" v-for="(item, index) in otherData" :key="index">
-          <div class="left">
-            <div class="row">RFID标签:{{ item.rfidCode }}</div>
-            <div class="row">物料编码:{{ item.materialCode }}</div>
-            <div class="row">物料名称:{{ item.materialName }}</div>
-            <div class="row">最近操作:{{ item.lastOpera }}</div>
-          </div>
-          <div class="right">
-            <Button type="primary" ghost @click="add(item)" v-if="item.lastOpera.indexOf('入库') === -1">入库</Button>
-          </div>
-        </div>
-      </div>
-      <div v-else style="padding: 10px 0;color: #FFFFFF">暂无数据</div>
-  
-    </Modal>
-  </div>
-  </template>
-  
-  <script>
-  import MyNav from '@/components/my-nav'
-  import * as signalR from '@microsoft/signalr'
-  import { MessagePackHubProtocol } from '@microsoft/signalr-protocol-msgpack'
-  import withUrl from '@/config/withUrl'
-  import {GetHasTagMaterialList, PlcStorageIn, ReScan, GetScanRfidStocInOut, DelScanRfid} from '@/api/integrated'
-  import store from "@/store";
-  import {logOut} from "@/libs/util";
-  export default {
-    name: "store-in",
-    data() {
-      return {
-        scanShow: false,
-        show: false,
-        modal: false,
-        percent: 0,
-        addTimer: null,
-        overTimer: null,
-        reading: false,
-        connection: null,
-        data: [], // 左侧数据列表
-        scanData: {
-          rfidTagItems:[],
-          materialItems:[],
-        }, // 扫描数据
-        otherData: [], // 扫描辅助数据
-        tempDelData: [], // 临时删除列表
-        remark: ''
-      }
-    },
-    components: {
-      MyNav
-    },
-    methods: {
-      add (item) {
-        item.totalQuantity = item.qty
-        item.quantity = item.qty
-        // 辅助扫描的添加一个isTemp 标识以供删除区分
-        if (this.scanData.rfidTagItems.find(scan => scan.materialCode === item.materialCode)) {
-          this.$Message.error('物料已添加')
-        } else {
-          this.scanData.rfidTagItems.push({...item, isTemp: true})
-          this.scanData.materialItems.push({...item, isTemp: true})
-          this.$Message.info('添加成功')
-        }
-      },
-      cancel () {
-        this.remark = ''
-      },
-      cfm () {
-        this.show = false
-      },
-      /* 临时删除 */
-      del (item, index) {
-        if (item.isTemp) {
-          this.scanData.rfidTagItems.splice(index, 1)
-          this.scanData.materialItems.splice(index, 1)
-          /* 添加一个临时删除数据 用于再次扫描数据时过滤已临时删除的数据 */
-          this.tempDelData.push(item)
-        } else {
-          DelScanRfid({
-            rfid: item.rfidCode,
-            plcStationCode: sessionStorage.getItem('plcCode')
-          }).then(res => {
-            if (res.code === 0) {
-              this.$Message.info('删除成功!')
-              this.tempDelData.push(item)
-              this.getScanList()
-            }
-          })
-        }
-      },
-      /* 辅助扫描通知 */
-      helperHandle (data) {
-        this.otherData = data
-      },
-      /* 入库通知 */
-      inHandle() {
-        this.getScanList()
-        clearTimeout(this.overTimer)
-        this.overTimer = setTimeout(() => {
-          clearInterval(this.addTimer)
-          this.percent = 100
-          setTimeout(() => {
-            this.modal = false
-          }, 500)
-        }, 3000)
-      },
-      /* 是否通过 0否 1是 */
-      pass(type) {
-        if (type === 0) {
-          this.$Message.info('请重新扫描入库!')
-          this.scanData.rfidTagItems = []
-          this.scanData.materialItems = []
-          ReScan({
-            reScanType: 0,
-            storageType: sessionStorage.getItem('plcCode'),
-            storageDoor: sessionStorage.getItem('door')
-          })
-        } else if (type === 1) {
-          // 入库
-          PlcStorageIn({
-            storageDoor: sessionStorage.getItem('door'),
-            plcStationCode: sessionStorage.getItem('plcCode'),
-            rfidList: this.scanData.rfidTagItems.map(item => item.rfidCode),
-            remark: this.remark
-          }).then(res => {
-            if (res.code === 0) {
-              this.$Message.info('入库成功!')
-              logOut()
-              // this.$store.commit('setHasGetInfo', false)
-              // this.$store.commit('setToken', '')
-              // setTimeout(() => {
-              //   this.$router.push({
-              //     name: 'Home',
-              //     query: {
-              //       plcCode: sessionStorage.getItem('plcCode'),
-              //       door: sessionStorage.getItem('door')
-              //     }
-              //   })
-              // }, 500)
-            }
-          })
-        }
-      },
-      getList() {
-        /* 获取已贴标数据 */
-        GetHasTagMaterialList().then(res => {
-          if (res.code === 0) {
-            this.data = res.result
-          }
-        })
-      },
-      getScanList () {
-        GetScanRfidStocInOut({
-          storagePlcCode: sessionStorage.getItem('plcCode'),
-          stockInOutScanType: 0
-        }).then(scanRes => {
-          if (scanRes.code === 0) {
-            this.reading = false
-            this.scanData = scanRes.result
-            /* 临时删除的数据不可再添加到出入库列表中 */
-            this.tempDelData.forEach(temp => {
-              for (const index in this.scanData.rfidTagItems) {
-                if (temp.materialCode === this.scanData.rfidTagItems[index].materialCode) {
-                  this.scanData.rfidTagItems.splice(index, 1)
-                }
-              }
-              for (const index in this.scanData.materialItems) {
-                if (temp.materialCode === this.scanData.materialItems[index].materialCode) {
-                  this.scanData.materialItems.splice(index, 1)
-                }
-              }
-            })
-            this.data.forEach(item => {
-              this.scanData.rfidTagItems.forEach(scan => {
-                if (item.rfidCode === scan.rfidCode) {
-                  item.checked = true
-                }
-              })
-            })
-          }
-        })
-      }
-    },
-    mounted() {
-      this.tempDelData = []
-      this.getList()
-      this.getScanList()
-      this.addTimer = setInterval(() => {
-        this.percent += 1
-        if (this.percent === 100) {
-          clearInterval(this.addTimer)
-          clearTimeout(this.overTimer)
-          this.modal = false
-        }
-      }, 100)
-      this.overTimer = setTimeout(() => {
-        clearInterval(this.addTimer)
-        this.percent = 100
-        setTimeout(() => {
-          this.modal = false
-        }, 500)
-      }, 3000)
-    },
-    destroyed() {
-    }
-  }
-  </script>
-  
-  <style lang="scss" scoped>
-    .container {
-      width: 100vw;
-      height: 100vh;
-      overflow: auto;
-      //background: rgba(2, 125, 180, 1);
-      background-image: linear-gradient(270deg,
-          #2c3034 0%,
-          #50575e 49%,
-          #2c3034 100%);
-      .content {
-        margin: 10px;
-        height: calc(100% - 121.6px);
-        overflow: hidden;
-        box-sizing: border-box;
-        //background: rgba(1, 84, 120, 1);
-        border-radius: 10px;
-        .reading {
-          height: 100%;
-          display: flex;
-          align-items: center;
-          justify-content: center;
-          font-size: 36px;
-          font-weight: bold;
-          color: #00FFFF;
-        }
-        .title {
-          padding-bottom: 10px;
-          text-align: center;
-          font-size: 36px;
-          font-weight: bold;
-          color: #2dc57c;
-        }
-        .main {
-          height: calc(100% - 113.6px);
-          display: flex;
-          flex-direction: column;
-          .list-wrap {
-            flex: 2;
-            overflow: hidden;
-            padding: 0 10px;
-            width: 100%;
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-            .list {
-              position: relative;
-              //padding: 0 10px;
-              flex: 1;
-              height: 100%;
-              overflow: hidden;
-              //background: rgba(2, 125, 180, 0.486274509803922);
-              background: #2c3034;
-              border-radius: 4px;
-              border: solid 1px #3879e7;
-              .sub-title {
-                position: relative;
-                padding: 5px 0;
-                font-size: 24px;
-                color: #0077ff;
-                font-weight: bold;
-                .remark {
-                  position: absolute;
-                  right: 10px;
-                  top: 50%;
-                  transform: translateY(-50%);
-                  font-size: 16px;
-                  font-weight: normal;
-                  color: #0077ff;
-                }
-              }
-              .row {
-                padding: 5px 0;
-                display: flex;
-                justify-content: space-between;
-                align-items: center;
-                //background: rgba(2, 167, 240, 1);
-                border-top: 1px solid #2655ad;
-                //border-radius: 5px;
-                &:last-child {
-                  border-bottom: 1px solid #2655ad;
-                }
-                .col {
-                  padding: 0 5px;
-                  display: flex;
-                  flex-direction: column;
-                  align-items: flex-start;
-                  justify-content: center;
-                  text-align: left;
-                  color: #ffffff;
-                }
-              }
-              .total {
-                padding: 5px 10px;
-                //position: absolute;
-                left: 0;
-                bottom: 0;
-                text-align: left;
-                font-size: 20px;
-                font-weight: bold;
-                color: #F59A23;
-                .top {
-                  font-size: 24px;
-                }
-                .label {
-                  margin-left: 40px  ;
-                  display: inline-block;
-                  width: 100px;
-                }
-              }
-            }
-          }
-          .bottom {
-            margin-top: 20px;
-            flex: 1;
-            .row {
-              border: none !important;
-            }
-            .col {
-              padding: 0 20px !important;
-            }
-          }
-        }
-        .footer {
-          padding: 10px 0;
-          padding-bottom: 0;
-          /deep/ .ivu-btn-large {
-            border-radius: 20px;
-            font-weight: bold;
-            width: 150px;
-          }
-        }
-      }
-    }
-    /deep/.ivu-modal-content {
-      background: #2c3034;
-    }
-    /deep/.ivu-modal-body {
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      padding: 0;
-    }
-    /deep/.remark-content {
-      padding: 16px;
-      width: 100%;
-      .title {
-        font-size: 24px;
-        font-weight: bold;
-        text-align: center;
-        color: #FFFFFF;
-        padding-bottom: 10px;
-      }
-      .btn {
-        text-align: center;
-        padding-top: 10px;
-      }
-    }
-    /deep/ .ivu-modal-header {
-      border-bottom: none;
-    }
-    /deep/ .ivu-modal-footer {
-      border-top: none;
-    }
-    .scan-title {
-      font-size: 18px;
-      font-weight: bold;
-      color: #FFFFFF;
-    }
-    .scan-btn {
-      text-align: center;
-    }
-    .scan-content {
-      padding: 10px 16px;
-      width: 100%;
-      max-height: 40vh;
-      overflow: auto;
-      background-color: #3D3D3D;
-      color: #FFFFFF;
-      .item {
-        margin-bottom: 5px;
-        border-bottom: 1px solid #FFFFFF;
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        &:last-child {
-          margin-bottom: 0;
-          border-bottom: none;
-        }
-        .left {
-          flex: 1;
-          overflow: hidden;
-        }
-        .right {
-          width: 60px;
-          /deep/ .ivu-btn-primary {
-            background-color: rgb(204, 228, 255);
-          }
-        }
-        .row {
-          margin-bottom: 5px;
-          word-break: break-all;
-        }
-      }
-    }
-  </style>
-  

+ 1051 - 0
src/views/store-in-2.vue

@@ -0,0 +1,1051 @@
+<template>
+	<div class="container">
+		<my-nav
+			@listener-in="inHandle"
+			@listener-helper="helperHandle"
+		></my-nav>
+		<div class="content">
+			<div class="reading" v-if="reading">
+				入库扫描中<br />
+				请将需要入库的物料推入感应门
+			</div>
+			<div v-else style="height: 100%">
+				<div
+					style="
+						display: flex;
+						justify-content: space-between;
+						align-items: center;
+					"
+				>
+					<div style="width: 108px"></div>
+					<div class="title">入库扫描</div>
+					<div style="padding: 0 10px">
+						<Button
+							type="primary"
+							style="margin-right: 10px"
+							@click="purContractPageListModal = true"
+							>手动入库</Button
+						>
+						<Button type="primary" @click="scanShow = true"
+							>辅助扫描</Button
+						>
+					</div>
+				</div>
+				<div class="main">
+					<div class="list-wrap">
+						<div class="list" style="margin-right: 20px">
+							<div class="sub-title">已贴标物料</div>
+							<div
+								style="
+									height: calc(100% - 46px);
+									overflow: auto;
+								"
+							>
+								<div
+									class="row"
+									v-for="(item, index) in data"
+									:key="index"
+								>
+									<div
+										class="col"
+										style="width: 50px; align-items: center"
+									>
+										<Icon
+											type="ios-checkmark-circle"
+											color="red"
+											size="18"
+											v-if="item.checked"
+										/>
+									</div>
+									<div class="col" style="flex: 1">
+										<div>{{ item.materialName }}</div>
+										<div>
+											物料长度:{{ item.quantity }}米
+										</div>
+									</div>
+								</div>
+							</div>
+						</div>
+						<div class="list">
+							<div class="sub-title">本次入库</div>
+							<div
+								style="
+									height: calc(100% - 46px);
+									overflow: auto;
+								"
+							>
+								<div
+									class="row"
+									v-for="(
+										item, index
+									) in scanData.rfidTagItems"
+									:key="index"
+								>
+									<div
+										class="col"
+										style="width: 50px; align-items: center"
+									></div>
+									<div
+										class="col"
+										style="flex: 1"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>{{ item.materialName }}</div>
+										<div>
+											物料长度:{{ item.quantity || 0 }}米
+										</div>
+									</div>
+									<div
+										class="col"
+										style="flex: 1"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>标签值:{{ item.rfid }}</div>
+									</div>
+									<div class="col" style="width: 50px">
+										<Icon
+											type="ios-trash"
+											size="20"
+											color="red"
+											@click="del(item, index)"
+											style="cursor: pointer"
+										/>
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+					<div class="list-wrap bottom">
+						<div class="list">
+							<div class="sub-title">
+								本次统计
+								<a class="remark" href="#" @click="show = true"
+									>填写备注</a
+								>
+							</div>
+							<div
+								style="
+									height: calc(100% - 46px);
+									overflow: auto;
+								"
+							>
+								<div
+									class="row"
+									v-for="(item, index) in materialItemsCopy"
+									:key="index"
+								>
+									<div
+										class="col"
+										style="flex: 3"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>{{ item.materialName }}</div>
+									</div>
+									<div
+										class="col"
+										style="flex: 2"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>入库件数:{{ item.tagCount }}</div>
+									</div>
+									<div
+										class="col"
+										style="flex: 2"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>
+											入库数量:{{ item.quantity }}米
+										</div>
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="footer">
+					<Button
+						type="error"
+						size="large"
+						style="margin-right: 20px"
+						@click="pass(0)"
+						>重新扫描</Button
+					>
+					<Button type="success" size="large" @click="pass(1)"
+						>确认无误</Button
+					>
+				</div>
+			</div>
+		</div>
+		<div class="remark-content">
+			<Modal
+				v-model="modal"
+				:mask-closable="false"
+				:closable="false"
+				:fullscreen="true"
+				:footer-hide="true"
+			>
+				<Progress
+					:percent="percent"
+					:stroke-color="['#108ee9', '#87d068']"
+					:hide-info="true"
+					style="width: 400px"
+				/>
+			</Modal>
+		</div>
+		<!-- 填写备注 -->
+		<Modal
+			v-model="show"
+			:closable="false"
+			:footer-hide="true"
+			class-name="vertical-center-modal"
+			@on-cancel="cancel"
+		>
+			<div class="remark-content">
+				<div class="title">填写备注</div>
+				<Input v-model="remark" type="textarea" :rows="10" />
+				<div class="btn">
+					<Button @click="cfm" type="success" style="width: 120px"
+						>确定</Button
+					>
+				</div>
+			</div>
+		</Modal>
+		<!-- 手动入库 -->
+		<Modal
+			v-model="purContractPageListModal"
+			title="手动入库"
+			okText="关闭"
+			class-name="purContractPageList"
+			@on-cancel="purContractPageListModal = false"
+			width="90%"
+		>
+			<my-table
+				:data="purContractPageListData"
+				:columns="purContractPageListColumns"
+				:table-filter="tableFilter"
+				:table-page="params"
+				@event-handle="eventHandle"
+				@on-change="changePage"
+			></my-table>
+		</Modal>
+		<my-manege-modal
+			v-model="showInfo"
+			:data="formData"
+			@approval-handle="approvalHandle"
+		>
+		</my-manege-modal>
+		<!-- 辅助扫描 -->
+		<Modal
+			v-model="scanShow"
+			class-name="vertical-center-modal"
+			@on-cancel="cancel"
+		>
+			<div class="scan-title" slot="header">辅助扫描</div>
+			<div class="scan-btn" slot="footer">
+				<Button
+					type="primary"
+					style="width: 80px"
+					@click="scanShow = false"
+					>关闭</Button
+				>
+			</div>
+			<div class="scan-content" v-if="otherData.length > 0">
+				<div
+					class="item"
+					v-for="(item, index) in otherData"
+					:key="index"
+				>
+					<div class="left">
+						<div class="row">RFID标签:{{ item.rfidCode }}</div>
+						<div class="row">物料编码:{{ item.materialCode }}</div>
+						<div class="row">物料名称:{{ item.materialName }}</div>
+						<div class="row">最近操作:{{ item.lastOpera }}</div>
+					</div>
+					<div class="right">
+						<Button
+							type="primary"
+							ghost
+							@click="add(item)"
+							v-if="item.lastOpera.indexOf('入库') === -1"
+							>入库</Button
+						>
+					</div>
+				</div>
+			</div>
+			<div v-else style="padding: 10px 0; color: #ffffff">暂无数据</div>
+		</Modal>
+	</div>
+</template>
+  
+  <script>
+import MyNav from '@/components/my-nav'
+import * as signalR from '@microsoft/signalr'
+import { MessagePackHubProtocol } from '@microsoft/signalr-protocol-msgpack'
+import withUrl from '@/config/withUrl'
+import MyTable from '@/components/my-table/my-table'
+import {
+	GetHasTagMaterialList,
+	PlcStorageIn,
+	ReScan,
+	GetScanRfidStocInOut,
+	DelScanRfid,
+	GetPurContractPageList,
+} from '@/api/integrated'
+import store from '@/store'
+import { logOut } from '@/libs/util'
+import MyManegeModal from './my-manage-modal'
+export default {
+	name: 'store-in',
+	components: {
+		MyTable,
+		MyNav,
+		MyManegeModal,
+	},
+	
+
+	data() {
+		return {
+			scanShow: false,
+			show: false,
+			modal: false,
+			percent: 0,
+			addTimer: null,
+			overTimer: null,
+			reading: false,
+			connection: null,
+			data: [], // 左侧数据列表
+			scanData: {
+				rfidTagItems: [],
+				materialItems: [],
+			}, // 扫描数据
+			otherData: [], // 扫描辅助数据
+			tempDelData: [], // 临时删除列表
+			remark: '',
+			materialItemsCopy: [],
+			// 手动入库
+			showInfo: false,
+			formData: {},
+			purContractPageListModal: false,
+			purContractPageListData: [],
+			purContractPageListColumns: [
+				{
+					title: '序号',
+					type: 'index',
+					width: 60,
+					align: 'center',
+				},
+				{
+					title: '合同编号',
+					key: 'purchaseBillNo',
+					minWidth: 200,
+					render: (h, params) => {
+						let _this = this
+						return h(
+							'a',
+							{
+								on: {
+									click() {},
+								},
+							},
+							params.row.purchaseBillNo
+						)
+					},
+				},
+				{
+					title: '合同状态',
+					key: 'supplierShipState',
+					minWidth: 150,
+				},
+				{
+					title: '交货日期',
+					key: 'deliverTime',
+					minWidth: 150,
+				},
+				{
+					title: '件号',
+					key: 'materialCode',
+					minWidth: 150,
+				},
+				{
+					title: '物料名称',
+					key: 'materialName',
+					minWidth: 150,
+				},
+				{
+					title: '规格',
+					key: 'spec',
+					minWidth: 150,
+				},
+				{
+					title: '单位',
+					key: 'unitName',
+					minWidth: 150,
+				},
+				{
+					title: '采购数量',
+					key: 'purchaseQty',
+					minWidth: 150,
+				},
+				{
+					title: '单价',
+					key: 'price',
+					minWidth: 150,
+				},
+				{
+					title: '小计',
+					key: 'totalAmount',
+					minWidth: 150,
+				},
+				{
+					title: '已出货',
+					key: 'shipQuantity',
+					minWidth: 150,
+				},
+				{
+					title: '已出货金额',
+					key: 'shipAmount',
+					minWidth: 150,
+				},
+				{
+					title: '操作',
+					key: 'takeState',
+					minWidth: 180,
+					align: 'center',
+					fixed: 'right',
+					render: (h, params) => {
+						let _this = this
+						return h('div', [
+							h(
+								'Button',
+								{
+									props: {
+										type: 'primary',
+										size: 'small',
+									},
+									style: {
+										marginRight: '10px',
+									},
+									on: {
+										click: () => {
+											_this.formData = {
+												...params.row,
+											}
+											_this.showInfo = true
+										},
+									},
+								},
+								'查看批次'
+							),
+						])
+					},
+				},
+			],
+			tableFilter: [
+				{
+					name: 'Input',
+					value: 'key',
+					placeholder: '请输入关键字',
+				},
+				{
+					name: 'Button',
+					type: 'primary',
+					text: '查询',
+					e: 'search',
+				},
+			],
+			params: {
+				pageIndex: 1,
+				pageSize: 10,
+				total: 0,
+				supplierShipState: 0,
+			},
+			ws:null,
+		}
+	},
+	methods: {
+		add(item) {
+			item.totalQuantity = item.qty
+			item.quantity = item.qty
+			// 辅助扫描的添加一个isTemp 标识以供删除区分
+			if (
+				this.scanData.rfidTagItems.find(
+					(scan) => scan.materialCode === item.materialCode
+				)
+			) {
+				this.$Message.error('物料已添加')
+			} else {
+				this.scanData.rfidTagItems.push({ ...item, isTemp: true })
+				this.scanData.materialItems.push({ ...item, isTemp: true })
+				this.$Message.info('添加成功')
+			}
+		},
+		cancel() {
+			this.remark = ''
+		},
+		cfm() {
+			this.show = false
+		},
+		/* 临时删除 */
+		del(item, index) {
+			// if (item.isTemp) {
+			this.scanData.rfidTagItems.splice(index, 1)
+			this.scanData.materialItems.splice(index, 1)
+			/* 添加一个临时删除数据 用于再次扫描数据时过滤已临时删除的数据 */
+			this.tempDelData.push(item)
+			this.materialItemsCopy = []
+			for (
+				let i = 0;
+				i < this.scanData.rfidTagItems.length;
+				i++
+			) {
+				const element = this.scanData.rfidTagItems[i]
+				
+				if (this.materialItemsCopy.length == 0) {
+					this.materialItemsCopy.push({
+						...element,
+						tagCount: 1,
+					})
+				} else {
+					var isTotal = false
+
+					for (
+						let j = 0;
+						j < this.materialItemsCopy.length;
+						j++
+					) {
+						const jelement = this.materialItemsCopy[j]
+						if (
+							element.materialCode ===
+							jelement.materialCode
+						) {
+							isTotal = true
+							jelement.tagCount++
+							jelement.quantity += element.quantity
+						}
+					}
+					if (!isTotal)
+						this.materialItemsCopy.push({
+							...element,
+							tagCount: 1,
+						})
+				}
+			}
+		},
+		/* 辅助扫描通知 */
+		helperHandle(data) {
+			this.otherData = data
+		},
+		/* 入库通知 */
+		inHandle() {
+			this.getScanList()
+			clearTimeout(this.overTimer)
+			this.overTimer = setTimeout(() => {
+				clearInterval(this.addTimer)
+				this.percent = 100
+				setTimeout(() => {
+					this.modal = false
+				}, 500)
+			}, 3000)
+		},
+		/* 是否通过 0否 1是 */
+		pass(type) {
+			if (type === 0) {
+				this.$Message.info('请重新扫描入库!')
+				this.scanData.rfidTagItems = []
+				this.scanData.materialItems = []
+				this.materialItemsCopy = []
+				this.tempDelData = []
+				if(window.ws) window.ws.close()
+				setTimeout(() => {
+					this.socketInit()
+				}, 500);
+			} else if (type === 1) {
+				// 入库
+				PlcStorageIn({
+					storageDoor: sessionStorage.getItem('door'),
+					plcStationCode: sessionStorage.getItem('plcCode'),
+					rfidList: this.scanData.rfidTagItems.map(
+						(item) => item.rfid
+					),
+					remark: this.remark,
+				}).then((res) => {
+					if (res.code === 0) {
+						this.$Message.info('入库成功!')
+						logOut()
+						// this.$store.commit('setHasGetInfo', false)
+						// this.$store.commit('setToken', '')
+						// setTimeout(() => {
+						//   this.$router.push({
+						//     name: 'Home',
+						//     query: {
+						//       plcCode: sessionStorage.getItem('plcCode'),
+						//       door: sessionStorage.getItem('door')
+						//     }
+						//   })
+						// }, 500)
+					}
+				})
+			}
+		},
+		getList() {
+			/* 获取已贴标数据 */
+			GetHasTagMaterialList().then((res) => {
+				if (res.code === 0) {
+					this.data = res.result
+				}
+			})
+		},
+		// 检索条件事件处理
+		eventHandle(option) {
+			switch (option._evnet) {
+				case 'search':
+					this.params.pageIndex = 1
+					this.params.purchaseBillNo = option.key
+					this.params.supplierShipState = option.supplierShipState
+					this.gePurContractPage()
+					break
+				case 'add':
+					this.formType = 'add'
+					this.show = true
+					break
+				case 'back':
+					this.$router.go(-1)
+					break
+				case 'download':
+					window.open(
+						'https://fzjx.oss-cn-hangzhou.aliyuncs.com/order/20211014/211014041759903892.xlsx'
+					)
+					break
+				case 'ip':
+					this.ipShow = true
+					break
+			}
+		},
+		/* 点击删除 出货后触发审批流操作 */
+		approvalHandle() {
+			this.getList()
+		},
+		changePage(pageIndex) {
+			this.params.pageIndex = pageIndex
+			this.gePurContractPage()
+		},
+		gePurContractPage() {
+			GetPurContractPageList(this.params).then((res) => {
+				if (res.code === 0) {
+					this.purContractPageListData = res.result.list
+					this.params.total = res.result.totalCount
+				}
+			})
+		},
+		unique(arr, val) {
+			const res = new Map()
+			return arr.filter(
+				(item) => !res.has(item[val]) && res.set(item[val], 1)
+			)
+		},
+		getScanList(rfidTagItems) {
+			if(!rfidTagItems) return
+			this.reading = false
+			console.log(rfidTagItems)
+			this.scanData.rfidTagItems = [
+				...this.scanData.rfidTagItems,
+				...rfidTagItems,
+			]
+			this.scanData.materialItems = [
+				...this.scanData.materialItems,
+			]
+			this.scanData.rfidTagItems = this.unique(
+				this.scanData.rfidTagItems,
+				'rfid'
+			)
+			/* 临时删除的数据不可再添加到出入库列表中 */
+			this.tempDelData.forEach((temp) => {
+				for (const index in this.scanData.rfidTagItems) {
+					if (
+						temp.rfid ===
+						this.scanData.rfidTagItems[index].rfid
+					) {
+						this.scanData.rfidTagItems.splice(index, 1)
+					}
+				}
+
+				for (const index in this.scanData.materialItems) {
+					if (
+						temp.materialCode ===
+						this.scanData.materialItems[index].materialCode
+					) {
+						this.scanData.materialItems.splice(index, 1)
+					}
+				}
+			})
+			this.materialItemsCopy = []
+			for (
+				let i = 0;
+				i < this.scanData.rfidTagItems.length;
+				i++
+			) {
+				const element = this.scanData.rfidTagItems[i]
+				
+				if (this.materialItemsCopy.length == 0) {
+					this.materialItemsCopy.push({
+						...element,
+						tagCount: 1,
+					})
+				} else {
+					var isTotal = false
+
+					for (
+						let j = 0;
+						j < this.materialItemsCopy.length;
+						j++
+					) {
+						const jelement = this.materialItemsCopy[j]
+						if (
+							element.materialCode ===
+							jelement.materialCode
+						) {
+							isTotal = true
+							jelement.tagCount++
+							jelement.quantity += element.quantity
+						}
+					}
+					if (!isTotal)
+						this.materialItemsCopy.push({
+							...element,
+							tagCount: 1,
+						})
+				}
+			}
+			
+			this.data.forEach((item) => {
+				this.scanData.rfidTagItems.forEach((scan) => {
+					if (item.rfid === scan.rfid) {
+						item.checked = true
+					}
+				})
+			})
+		},
+		socketInit() {
+			const v = this
+			window.ws = new WebSocket(
+				'ws://120.79.80.64:8050/cloudApi/webStock/' + window.localStorage.getItem('jobNo')
+				//'ws://192.168.1.97:8300/webStock/' + window.localStorage.getItem('token')
+			)
+			//申请一个WebSocket对象,参数是服务端地址,同http协议使用http://开头一样,WebSocket协议的url使用ws://开头,另外安全的WebSocket协议使用wss://开头
+			window.ws.onopen = function () {
+				//当WebSocket创建成功时,触发onopen事件
+				console.log('open')
+				
+			}
+			window.ws.onmessage = function (e) {
+				//当客户端收到服务端发来的消息时,触发onmessage事件,参数e.data包含server传递过来的数据
+				
+				var msg = JSON.parse(e.data)
+				if (msg.type == 1) {
+					msg.data.instructions = 'in' + sessionStorage.getItem('plcCode')
+					msg.data.businessType = 1
+					// 仓库id: 一楼仓库'c185883dba22478cb593d33f6b66cc53' 四楼仓库'0b8f584250bb4b40b72d641ce4849d15'
+					msg.data.stockHouseId = sessionStorage.getItem('plcCode') == 2 ? '0b8f584250bb4b40b72d641ce4849d15' : 'c185883dba22478cb593d33f6b66cc53',
+					msg.data.type = 2
+					msg.type = 2
+					window.ws.send(JSON.stringify(msg))
+				}
+				if(msg.type == 3){
+					console.log(msg.data.rfidData)
+					v.getScanList(msg.data.rfidData)
+				}
+			}
+			window.ws.onclose = function (e) {
+				//当客户端收到服务端发送的关闭连接请求时,触发onclose事件
+				console.log('close')
+			}
+			window.ws.onerror = function (e) {
+				//如果出现连接、处理、接收、发送数据失败的时候触发onerror事件
+				console.log(error)
+			}
+		},
+	},
+	
+	mounted() {
+		this.gePurContractPage()
+		this.socketInit()
+		this.tempDelData = []
+		this.getList()
+		//this.getScanList()
+		this.addTimer = setInterval(() => {
+			this.percent += 1
+			if (this.percent === 100) {
+				clearInterval(this.addTimer)
+				clearTimeout(this.overTimer)
+				this.modal = false
+			}
+		}, 100)
+		this.overTimer = setTimeout(() => {
+			clearInterval(this.addTimer)
+			this.percent = 100
+			setTimeout(() => {
+				this.modal = false
+			}, 500)
+		}, 3000)
+	},
+	destroyed() {},
+	
+}
+</script>
+<style>
+.purContractPageList .table-filter,
+.purContractPageList .table-page,
+.purContractPageList .ivu-modal-footer,
+.purContractPageList .ivu-modal-header {
+	background: #fff;
+}
+
+.purContractPageList .table-content,
+.purContractPageList .container {
+	height: auto !important;
+}
+</style>
+  <style lang="scss" scoped>
+.container {
+	width: 100vw;
+	height: 100vh;
+	overflow: auto;
+	//background: rgba(2, 125, 180, 1);
+	background-image: linear-gradient(
+		270deg,
+		#2c3034 0%,
+		#50575e 49%,
+		#2c3034 100%
+	);
+	.content {
+		margin: 10px;
+		height: calc(100% - 121.6px);
+		overflow: hidden;
+		box-sizing: border-box;
+		//background: rgba(1, 84, 120, 1);
+		border-radius: 10px;
+		.reading {
+			height: 100%;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			font-size: 36px;
+			font-weight: bold;
+			color: #00ffff;
+		}
+		.title {
+			padding-bottom: 10px;
+			text-align: center;
+			font-size: 36px;
+			font-weight: bold;
+			color: #2dc57c;
+		}
+		.main {
+			height: calc(100% - 113.6px);
+			display: flex;
+			flex-direction: column;
+			.list-wrap {
+				flex: 2;
+				overflow: hidden;
+				padding: 0 10px;
+				width: 100%;
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				.list {
+					position: relative;
+					//padding: 0 10px;
+					flex: 1;
+					height: 100%;
+					overflow: hidden;
+					//background: rgba(2, 125, 180, 0.486274509803922);
+					background: #2c3034;
+					border-radius: 4px;
+					border: solid 1px #3879e7;
+					.sub-title {
+						position: relative;
+						padding: 5px 0;
+						font-size: 24px;
+						color: #0077ff;
+						font-weight: bold;
+						.remark {
+							position: absolute;
+							right: 10px;
+							top: 50%;
+							transform: translateY(-50%);
+							font-size: 16px;
+							font-weight: normal;
+							color: #0077ff;
+						}
+					}
+					.row {
+						padding: 5px 0;
+						display: flex;
+						justify-content: space-between;
+						align-items: center;
+						//background: rgba(2, 167, 240, 1);
+						border-top: 1px solid #2655ad;
+						//border-radius: 5px;
+						&:last-child {
+							border-bottom: 1px solid #2655ad;
+						}
+						.col {
+							padding: 0 5px;
+							display: flex;
+							flex-direction: column;
+							align-items: flex-start;
+							justify-content: center;
+							text-align: left;
+							color: #ffffff;
+						}
+					}
+					.total {
+						padding: 5px 10px;
+						//position: absolute;
+						left: 0;
+						bottom: 0;
+						text-align: left;
+						font-size: 20px;
+						font-weight: bold;
+						color: #f59a23;
+						.top {
+							font-size: 24px;
+						}
+						.label {
+							margin-left: 40px;
+							display: inline-block;
+							width: 100px;
+						}
+					}
+				}
+			}
+			.bottom {
+				margin-top: 20px;
+				flex: 1;
+				.row {
+					border: none !important;
+				}
+				.col {
+					padding: 0 20px !important;
+				}
+			}
+		}
+		.footer {
+			padding: 10px 0;
+			padding-bottom: 0;
+			/deep/ .ivu-btn-large {
+				border-radius: 20px;
+				font-weight: bold;
+				width: 150px;
+			}
+		}
+	}
+}
+/deep/.ivu-modal-content {
+	background: #2c3034;
+}
+/deep/.ivu-modal-body {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	padding: 0;
+}
+/deep/.remark-content {
+	padding: 16px;
+	width: 100%;
+	.title {
+		font-size: 24px;
+		font-weight: bold;
+		text-align: center;
+		color: #ffffff;
+		padding-bottom: 10px;
+	}
+	.btn {
+		text-align: center;
+		padding-top: 10px;
+	}
+}
+/deep/ .ivu-modal-header {
+	border-bottom: none;
+}
+/deep/ .ivu-modal-footer {
+	border-top: none;
+}
+.scan-title {
+	font-size: 18px;
+	font-weight: bold;
+	color: #ffffff;
+}
+.scan-btn {
+	text-align: center;
+}
+.scan-content {
+	padding: 10px 16px;
+	width: 100%;
+	max-height: 40vh;
+	overflow: auto;
+	background-color: #3d3d3d;
+	color: #ffffff;
+	.item {
+		margin-bottom: 5px;
+		border-bottom: 1px solid #ffffff;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		&:last-child {
+			margin-bottom: 0;
+			border-bottom: none;
+		}
+		.left {
+			flex: 1;
+			overflow: hidden;
+		}
+		.right {
+			width: 60px;
+			/deep/ .ivu-btn-primary {
+				background-color: rgb(204, 228, 255);
+			}
+		}
+		.row {
+			margin-bottom: 5px;
+			word-break: break-all;
+		}
+	}
+}
+</style>
+  

+ 1010 - 0
src/views/store-out-2.vue

@@ -0,0 +1,1010 @@
+<template>
+	<div class="container">
+		<my-nav
+			@listener-out="outHandle"
+			@listener-helper="helperHandle"
+		></my-nav>
+		<div class="content">
+			<div class="reading" v-if="reading">
+				出库扫描中<br />
+				请下架所需要的物料<br />
+				并将物料推出感应门
+			</div>
+			<div v-else style="height: 100%">
+				<div
+					style="
+						display: flex;
+						justify-content: space-between;
+						align-items: center;
+					"
+				>
+					<div style="width: 108px"></div>
+					<div class="title">出库扫描</div>
+					<div style="padding: 0 10px">
+						<Button type="primary" @click="scanShow = true"
+							>辅助扫描</Button
+						>
+					</div>
+				</div>
+				<div class="main">
+					<div class="list-wrap">
+						<div class="list" style="margin-right: 20px">
+							<div class="sub-title">领料信息</div>
+							<div
+								style="
+									height: calc(100% - 46px);
+									overflow: auto;
+								"
+							>
+								<div
+									class="row"
+									v-for="(item, index) in data"
+									:key="index"
+								>
+									<div
+										class="col"
+										style="width: 50px; align-items: center"
+									>
+										<Icon
+											type="ios-checkmark-circle"
+											color="red"
+											size="18"
+											v-if="item.checked"
+										/>
+									</div>
+									<div class="col" style="flex: 1">
+										<div>{{ item.materialName }}</div>
+										<div>
+											物料长度:{{ item.quantity }}米
+										</div>
+									</div>
+								</div>
+								<!-- <div
+									class="row"
+									v-for="(item) in newData"
+									:key="item.id"
+								>
+									<div
+										class="col"
+										style="width: 50px; align-items: center"
+									>
+										<Icon
+											type="ios-checkmark-circle"
+											color="red"
+											size="18"
+											v-if="item.checked"
+										/>
+									</div>
+									<div class="col" style="flex: 1">
+										<div>{{ item.materialName }}</div>
+										<div>
+											物料长度:{{ item.quantity }}米
+										</div>
+									</div>
+								</div> -->
+							</div>
+						</div>
+						<div class="list">
+							<div class="sub-title">本次出库</div>
+							<div
+								style="
+									height: calc(100% - 46px);
+									overflow: auto;
+								"
+							>
+								<div
+									class="row"
+									v-for="(
+										item, index
+									) in scanData.rfidTagItems"
+									:key="index"
+								>
+									<div
+										class="col"
+										style="width: 50px; align-items: center"
+									></div>
+									<div
+										class="col"
+										style="flex: 1; overflow: hidden"
+									>
+										标签值:{{
+											'**************' +
+											item.rfid.substr(-6, 6)
+										}}
+									</div>
+									<div
+										class="col"
+										style="flex: 1; overflow: hidden"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>{{ item.materialName }}</div>
+										<div>
+											物料长度:{{ item.quantity || 0 }}米
+										</div>
+									</div>
+									<div class="col" style="width: 50px">
+										<Icon
+											type="ios-trash"
+											size="20"
+											color="red"
+											@click="del(item, index)"
+											style="cursor: pointer"
+										/>
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+					<div class="list-wrap bottom">
+						<div class="list">
+							<div class="sub-title">
+								本次统计
+								<a
+									class="remark"
+									href="#"
+									@click="remarkShow = true"
+									>填写备注</a
+								>
+							</div>
+							<div
+								style="
+									height: calc(100% - 46px);
+									overflow: auto;
+								"
+							>
+								<div
+									class="row"
+									v-for="(item, index) in materialItemsCopy"
+									:key="index"
+								>
+									<div
+										class="col"
+										style="flex: 3"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>{{ item.materialName }}</div>
+									</div>
+									<div
+										class="col"
+										style="flex: 2"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>
+											出库件数:{{ item.tagCount || 1 }}
+										</div>
+									</div>
+									<div
+										class="col"
+										style="flex: 2"
+										:style="{
+											color:
+												item.scanRfidStatus === 1
+													? 'orange'
+													: item.scanRfidStatus === 2
+													? 'red'
+													: '#fff',
+										}"
+									>
+										<div>
+											出库数量:{{ item.quantity }}米
+										</div>
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="footer">
+					<Button
+						type="error"
+						size="large"
+						style="margin-right: 20px"
+						@click="pass(0)"
+						>重新扫描</Button
+					>
+					<Button
+						type="success"
+						size="large"
+						@click.native="copyData()"
+						>仓管校验</Button
+					>
+				</div>
+			</div>
+		</div>
+		<Modal
+			v-model="modal"
+			:mask-closable="false"
+			:closable="false"
+			:fullscreen="true"
+			:footer-hide="true"
+		>
+			<Progress
+				:percent="percent"
+				:stroke-color="['#108ee9', '#87d068']"
+				:hide-info="true"
+				style="width: 400px"
+			/>
+		</Modal>
+		<Modal
+			v-model="remarkShow"
+			:closable="false"
+			:footer-hide="true"
+			class-name="vertical-center-modal"
+			@on-cancel="cancel"
+		>
+			<div class="remark-content">
+				<div class="title">填写备注</div>
+				<Input v-model="remark" type="textarea" :rows="10" />
+				<div class="btn">
+					<Button @click="cfm" type="success" style="width: 120px"
+						>确定</Button
+					>
+				</div>
+			</div>
+		</Modal>
+		<!-- 辅助扫描 -->
+		<Modal
+			v-model="scanShow"
+			class-name="vertical-center-modal"
+			@on-cancel="cancel"
+		>
+			<div class="scan-title" slot="header">辅助扫描</div>
+			<div class="scan-btn" slot="footer">
+				<Button
+					type="primary"
+					style="width: 80px"
+					@click="scanShow = false"
+					>关闭</Button
+				>
+			</div>
+			<div class="scan-content" v-if="otherData.length > 0">
+				<div
+					class="item"
+					v-for="(item, index) in otherData"
+					:key="index"
+				>
+					<div class="left">
+						<div class="row">RFID标签:{{ item.rfidCode }}</div>
+						<div class="row">物料编码:{{ item.materialCode }}</div>
+						<div class="row">物料名称:{{ item.materialName }}</div>
+						<div class="row">最近操作:{{ item.lastOpera }}</div>
+					</div>
+					<div class="right">
+						<Button
+							type="primary"
+							ghost
+							@click="add(item)"
+							v-if="item.lastOpera.indexOf('入库') !== -1"
+							>{{item.check ? '已添加' : '添加'}}</Button
+						>
+					</div>
+				</div>
+			</div>
+			<div v-else style="padding: 10px 0; color: #ffffff">暂无数据</div>
+		</Modal>
+		<!-- 仓管人脸校验 -->
+		<Modal
+			v-model="show"
+			width="80%"
+			class-name="vertical-center-modal"
+			:footer-hide="true"
+		>
+			<check-modal @face-check="faceCheck"></check-modal>
+		</Modal>
+	</div>
+</template>
+
+<script>
+import MyNav from '@/components/my-nav'
+import * as signalR from '@microsoft/signalr'
+import withUrl from '@/config/withUrl'
+import { MessagePackHubProtocol } from '@microsoft/signalr-protocol-msgpack'
+import axios from 'axios'
+import {
+	PlcStorageOut,
+	ReScan,
+	GetApplyTakeStockOut,
+	GetScanRfidStocInOut,
+	DelScanRfid,
+} from '@/api/integrated'
+import { logOut } from '@/libs/util'
+import CheckModal from './check-modal'
+
+export default {
+	name: 'store-in',
+	data() {
+		return {
+			scanShow: false,
+			show: false,
+			modal: false,
+			percent: 0,
+			addTimer: null,
+			overTimer: null,
+			data: [], // 左侧数据列表
+			scanData: {
+				rfidTagItems: [],
+				materialItems: [],
+			}, // 扫描数据
+			otherData: [], // 扫描辅助数据
+			tempDelData: [], // 临时删除列表
+			connection: null,
+			reading: false,
+			remarkShow: false,
+			remark: '',
+			rfidTagItemsCopy: [],
+			newData: [],
+			//后台有bug 前端新建数据自己计算
+			materialItemsCopy: [],
+		}
+	},
+	components: {
+		MyNav,
+		CheckModal,
+	},
+	methods: {
+		copyData() {
+			this.show = true
+			this.rfidTagItemsCopy = JSON.parse(
+				JSON.stringify(this.scanData.rfidTagItems)
+			)
+		},
+		add(item) {
+			item.totalQuantity = item.qty
+			item.quantity = item.qty
+			item.check = true
+			// 辅助扫描的添加一个isTemp 标识以供删除区分
+			if (
+				this.scanData.rfidTagItems.find(
+					(scan) => scan.rfidCode === item.rfidCode
+				)
+			) {
+				this.$Message.error('物料已添加')
+			} else {
+				this.scanData.rfidTagItems.push({ ...item, isTemp: true })
+				this.scanData.materialItems.push({ ...item, isTemp: true })
+				this.materialItemsCopy = []
+					for (
+						let i = 0;
+						i < this.scanData.rfidTagItems.length;
+						i++
+					) {
+						const element = this.scanData.rfidTagItems[i]
+						console.log(this.materialItemsCopy, 12312312)
+						if (this.materialItemsCopy.length == 0) {
+							this.materialItemsCopy.push({
+								...element,
+								tagCount: 1,
+							})
+						} else {
+							var isTotal = false
+
+							for (
+								let j = 0;
+								j < this.materialItemsCopy.length;
+								j++
+							) {
+								const jelement = this.materialItemsCopy[j]
+								if (
+									element.materialCode ===
+									jelement.materialCode
+								) {
+									isTotal = true
+									jelement.tagCount++
+									jelement.quantity += element.quantity
+								}
+							}
+							if (!isTotal)
+								this.materialItemsCopy.push({
+									...element,
+									tagCount: 1,
+								})
+						}
+					}
+				this.$Message.info('添加成功')
+			}
+		},
+		cancel() {
+			this.remark = ''
+		},
+		cfm() {
+			this.remarkShow = false
+		},
+		faceCheck(val) {
+			const v = this
+			PlcStorageOut({
+				inOutStorageNo: '',
+				storageDoor: sessionStorage.getItem('door'),
+				plcStationCode: sessionStorage.getItem('plcCode'),
+				rfidList: this.rfidTagItemsCopy.map((item) => item.rfid),
+				remark: this.remark,
+			}).then(
+				(res) => {
+					if (res.code === 0) {
+						this.$Message.info('出库成功!')
+						const actual = []
+						for (
+							let i = 0;
+							i < v.scanData.rfidTagItems.length;
+							i++
+						) {
+							const element = v.scanData.rfidTagItems[i]
+							actual.push({
+								materialCode: element.materialCode,
+								materialRfid: element.rfidCode,
+								quantity: element.quantity,
+							})
+						}
+						axios
+							.post(
+								'/cloudApi/stockDetail/submitRestrictedPicking',
+								{
+									appointInfo: v.newData,
+									actual: actual,
+									jobNo: window.localStorage.getItem('jobNo'),
+								}
+							)
+							.then((res) => {})
+						logOut()
+					} else {
+						this.saveErr()
+					}
+				},
+				(err) => {
+					this.saveErr()
+				}
+			)
+		},
+		saveErr() {
+			const v = this
+			const errListJson = window.localStorage.getItem('errList')
+			if (errListJson) {
+				var errList = JSON.parse(errListJson)
+			} else {
+				var errList = []
+			}
+			var msg = []
+			for (let i = 0; i < v.scanData.rfidTagItems.length; i++) {
+				const element = v.scanData.rfidTagItems[i]
+				msg.push(element.rfid)
+			}
+			msg.push(window.localStorage.getItem('jobNo'))
+			msg.push(new Date())
+			errList.push(msg)
+			window.localStorage.setItem('errList', JSON.stringify(errList))
+		},
+		/* 临时删除 */
+		del(item, index) {
+			//if (item.isTemp) {
+			this.scanData.rfidTagItems.splice(index, 1)
+			this.scanData.materialItems.splice(index, 1)
+			/* 添加一个临时删除数据 用于再次扫描数据时过滤已临时删除的数据 */
+			this.tempDelData.push(item)
+			this.materialItemsCopy = []
+			for (
+				let i = 0;
+				i < this.scanData.rfidTagItems.length;
+				i++
+			) {
+				const element = this.scanData.rfidTagItems[i]
+				
+				if (this.materialItemsCopy.length == 0) {
+					this.materialItemsCopy.push({
+						...element,
+						tagCount: 1,
+					})
+				} else {
+					var isTotal = false
+
+					for (
+						let j = 0;
+						j < this.materialItemsCopy.length;
+						j++
+					) {
+						const jelement = this.materialItemsCopy[j]
+						if (
+							element.materialCode ===
+							jelement.materialCode
+						) {
+							isTotal = true
+							jelement.tagCount++
+							jelement.quantity += element.quantity
+						}
+					}
+					if (!isTotal)
+						this.materialItemsCopy.push({
+							...element,
+							tagCount: 1,
+						})
+				}
+			}
+		},
+		/* 辅助扫描通知 */
+		helperHandle(data) {
+			console.log(data)
+			data.map(item=>{
+				item.check = false
+			})
+			this.otherData = [...this.otherData, ...data]
+			this.otherData = this.unique(
+				this.otherData,
+				'rfidCode'
+			)
+		},
+		/* 出库通知 */
+		outHandle() {
+			this.getList()
+			clearTimeout(this.overTimer)
+			this.overTimer = setTimeout(() => {
+				clearInterval(this.addTimer)
+				this.percent = 100
+				setTimeout(() => {
+					this.modal = false
+				}, 500)
+			}, 3000)
+		},
+		/* 是否通过 0否 1是 */
+		pass(type) {
+			if (type === 0) {
+				this.$Message.info('请重新扫描出库!')
+				this.scanData.rfidTagItems = []
+				this.scanData.materialItems = []
+				this.materialItemsCopy = []
+				this.tempDelData = []
+				if(window.ws) window.ws.close()
+				setTimeout(() => {
+					this.socketInit()
+				}, 500);
+			} else if (type === 1) {
+				// 出库
+				console.log('pass口子')
+				PlcStorageOut({
+					inOutStorageNo: '',
+					storageDoor: sessionStorage.getItem('door'),
+					plcStationCode: sessionStorage.getItem('plcCode'),
+					rfidList: this.scanData.rfidTagItems.map(
+						(item) => item.rfidCode
+					),
+					remark: this.remark,
+				}).then((res) => {
+					if (res.code === 0) {
+						this.$Message.info('出库成功!')
+						logOut()
+					}
+				})
+			}
+		},
+		unique(arr, val) {
+			const res = new Map()
+			return arr.filter(
+				(item) => !res.has(item[val]) && res.set(item[val], 1)
+			)
+		},
+		getList(rfidTagItems) {
+			if(!rfidTagItems) return
+			this.reading = false
+			this.scanData.rfidTagItems = [
+				...this.scanData.rfidTagItems,
+				...rfidTagItems,
+			]
+			this.scanData.materialItems = [
+				...this.scanData.materialItems,
+			]
+			this.scanData.rfidTagItems = this.unique(
+				this.scanData.rfidTagItems,
+				'rfid'
+			)
+			/* 临时删除的数据不可再添加到出入库列表中 */
+			this.tempDelData.forEach((temp) => {
+				for (const index in this.scanData.rfidTagItems) {
+					if (
+						temp.rfid ===
+						this.scanData.rfidTagItems[index].rfid
+					) {
+						this.scanData.rfidTagItems.splice(index, 1)
+					}
+				}
+
+				for (const index in this.scanData.materialItems) {
+					if (
+						temp.materialCode ===
+						this.scanData.materialItems[index].materialCode
+					) {
+						this.scanData.materialItems.splice(index, 1)
+					}
+				}
+			})
+			this.materialItemsCopy = []
+			for (
+				let i = 0;
+				i < this.scanData.rfidTagItems.length;
+				i++
+			) {
+				const element = this.scanData.rfidTagItems[i]
+				
+				if (this.materialItemsCopy.length == 0) {
+					this.materialItemsCopy.push({
+						...element,
+						tagCount: 1,
+					})
+				} else {
+					var isTotal = false
+
+					for (
+						let j = 0;
+						j < this.materialItemsCopy.length;
+						j++
+					) {
+						const jelement = this.materialItemsCopy[j]
+						if (
+							element.materialCode ===
+							jelement.materialCode
+						) {
+							isTotal = true
+							jelement.tagCount++
+							jelement.quantity += element.quantity
+						}
+					}
+					if (!isTotal)
+						this.materialItemsCopy.push({
+							...element,
+							tagCount: 1,
+						})
+				}
+			}
+			console.log(this.data)
+			this.data.map(items => {
+				this.materialItemsCopy.map(copyData => {
+					
+				})
+			})
+			
+			//统计状态计算颜色
+			this.materialItemsCopy.forEach((copyData) => {
+				this.data.forEach((items) => {
+					if(copyData.materialCode === items.materialCode){
+						if(copyData.quantity >=  items.quantity){
+							copyData.scanRfidStatus = 1
+						}else{
+							copyData.scanRfidStatus = 3
+						}
+						throw new Error('End Loop')
+					}else{
+						copyData.scanRfidStatus = 2
+					}
+				})
+			})
+			//计算本次出库状态颜色
+			this.scanData.rfidTagItems.forEach((items) => {
+				this.materialItemsCopy.forEach((copyData) => {
+					items.scanRfidStatus = 3
+					if(copyData.materialCode === items.materialCode){
+						items.scanRfidStatus = copyData.scanRfidStatus
+					}
+				})
+			})
+			this.data.forEach((item) => {
+				this.scanData.rfidTagItems.forEach((scan) => {
+					if (item.materialCode === scan.materialCode) {
+						item.checked = true
+					}
+				})
+			})
+		},
+		/* 左侧列表 */
+		getApplyTakeStockOut() {
+			GetApplyTakeStockOut().then((res) => {
+				if (res.code === 0) {
+					this.data = res.result
+				}
+			})
+		},
+		socketInit() {
+			const v = this
+			window.ws = new WebSocket(
+				'ws://120.79.80.64:8050/cloudApi/webStock/' + window.localStorage.getItem('jobNo')
+				// 'ws://192.168.1.97:8300/webStock/' + window.localStorage.getItem('token')
+			)
+			//申请一个WebSocket对象,参数是服务端地址,同http协议使用http://开头一样,WebSocket协议的url使用ws://开头,另外安全的WebSocket协议使用wss://开头
+			window.ws.onopen = function () {
+				//当WebSocket创建成功时,触发onopen事件
+				console.log('open')
+				
+			}
+			window.ws.onmessage = function (e) {
+				//当客户端收到服务端发来的消息时,触发onmessage事件,参数e.data包含server传递过来的数据
+				
+				var msg = JSON.parse(e.data)
+				if (msg.type == 1) {
+					msg.data.instructions = 'out' + sessionStorage.getItem('plcCode')
+					msg.data.businessType = 2
+					// 仓库id: 一楼仓库'c185883dba22478cb593d33f6b66cc53' 四楼仓库'0b8f584250bb4b40b72d641ce4849d15'
+					msg.data.stockHouseId = sessionStorage.getItem('plcCode') == 2 ? '0b8f584250bb4b40b72d641ce4849d15' : 'c185883dba22478cb593d33f6b66cc53',
+					msg.data.type = 2
+					msg.type = 2
+					window.ws.send(JSON.stringify(msg))
+				}
+				if(msg.type == 3){
+					v.getList(msg.data.rfidData)
+				}
+				
+			}
+			window.ws.onclose = function (e) {
+				//当客户端收到服务端发送的关闭连接请求时,触发onclose事件
+				console.log('close')
+			}
+			window.ws.onerror = function (e) {
+				//如果出现连接、处理、接收、发送数据失败的时候触发onerror事件
+				console.log(error)
+			}
+		},
+	},
+	mounted() {
+		this.otherData = JSON.parse(this.$route.query.otherData)
+		this.newData = JSON.parse(this.$route.query.newData)
+		this.socketInit()
+		this.tempDelData = []
+		this.getApplyTakeStockOut()
+		
+		this.time = this.$dayjs().format('YYYY年MM月DD日 HH:mm')
+		this.timer = setInterval(() => {
+			this.time = this.$dayjs().format('YYYY年MM月DD日 HH:mm')
+		}, 1000)
+		this.addTimer = setInterval(() => {
+			this.percent += 1
+			if (this.percent === 100) {
+				clearInterval(this.addTimer)
+				clearTimeout(this.overTimer)
+				this.modal = false
+			}
+		}, 100)
+		this.overTimer = setTimeout(() => {
+			clearInterval(this.addTimer)
+			this.percent = 100
+			setTimeout(() => {
+				this.modal = false
+			}, 500)
+		}, 3000)
+		this.scanData.rfidTagItems = []
+		this.scanData.materialItems = []
+		this.materialItemsCopy = []
+		// ReScan({
+		// 	reScanType: 1,
+		// 	storageType: sessionStorage.getItem('plcCode'),
+		// 	storageDoor: sessionStorage.getItem('door'),
+		// })
+	},
+	destroyed() {
+		clearInterval(this.timer)
+	},
+}
+</script>
+
+<style lang="scss" scoped>
+.container {
+	width: 100vw;
+	height: 100vh;
+	overflow: auto;
+	//background: rgba(2, 125, 180, 1);
+	background-image: linear-gradient(
+		270deg,
+		#2c3034 0%,
+		#50575e 49%,
+		#2c3034 100%
+	);
+	.content {
+		margin: 10px;
+		height: calc(100% - 121.6px);
+		overflow: hidden;
+		box-sizing: border-box;
+		//background: rgba(1, 84, 120, 1);
+		border-radius: 10px;
+		.reading {
+			height: 100%;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			font-size: 36px;
+			font-weight: bold;
+			color: #00ffff;
+		}
+		.title {
+			padding-bottom: 10px;
+			text-align: center;
+			font-size: 36px;
+			font-weight: bold;
+			color: #2dc57c;
+		}
+		.main {
+			height: calc(100% - 113.6px);
+			display: flex;
+			flex-direction: column;
+			.list-wrap {
+				flex: 2;
+				overflow: hidden;
+				padding: 0 10px;
+				width: 100%;
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				.list {
+					position: relative;
+					//padding: 0 10px;
+					flex: 1;
+					height: 100%;
+					overflow: hidden;
+					//background: rgba(2, 125, 180, 0.486274509803922);
+					background: #2c3034;
+					border-radius: 4px;
+					border: solid 1px #3879e7;
+					.sub-title {
+						position: relative;
+						padding: 5px 0;
+						font-size: 24px;
+						color: #0077ff;
+						font-weight: bold;
+						.remark {
+							position: absolute;
+							right: 10px;
+							top: 50%;
+							transform: translateY(-50%);
+							font-size: 16px;
+							font-weight: normal;
+							color: #0077ff;
+						}
+					}
+					.row {
+						padding: 5px 0;
+						display: flex;
+						justify-content: space-between;
+						align-items: center;
+						//background: rgba(2, 167, 240, 1);
+						border-top: 1px solid #2655ad;
+						//border-radius: 5px;
+						&:last-child {
+							border-bottom: 1px solid #2655ad;
+						}
+						.col {
+							padding: 0 5px;
+							display: flex;
+							flex-direction: column;
+							align-items: flex-start;
+							justify-content: center;
+							text-align: left;
+							color: #ffffff;
+						}
+					}
+					.total {
+						padding: 5px 10px;
+						//position: absolute;
+						left: 0;
+						bottom: 0;
+						text-align: left;
+						font-size: 20px;
+						font-weight: bold;
+						color: #f59a23;
+						.top {
+							font-size: 24px;
+						}
+						.label {
+							margin-left: 40px;
+							display: inline-block;
+							width: 100px;
+						}
+					}
+				}
+			}
+			.bottom {
+				margin-top: 20px;
+				flex: 1;
+				.row {
+					border: none !important;
+				}
+				.col {
+					padding: 0 20px !important;
+				}
+			}
+		}
+		.footer {
+			padding: 10px 0;
+			padding-bottom: 0;
+			/deep/ .ivu-btn-large {
+				border-radius: 20px;
+				font-weight: bold;
+				width: 150px;
+			}
+		}
+	}
+}
+/deep/.ivu-modal-content {
+	background: #2c3034;
+}
+/deep/.ivu-modal-body {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	padding: 0;
+}
+/deep/.remark-content {
+	padding: 16px;
+	width: 100%;
+	.title {
+		font-size: 24px;
+		font-weight: bold;
+		text-align: center;
+		color: #ffffff;
+		padding-bottom: 10px;
+	}
+	.btn {
+		text-align: center;
+		padding-top: 10px;
+	}
+}
+/deep/ .ivu-modal-header {
+	border-bottom: none;
+}
+/deep/ .ivu-modal-footer {
+	border-top: none;
+}
+.scan-title {
+	font-size: 18px;
+	font-weight: bold;
+	color: #ffffff;
+}
+.scan-btn {
+	text-align: center;
+}
+.scan-content {
+	padding: 10px 16px;
+	width: 100%;
+	max-height: 40vh;
+	overflow: auto;
+	background-color: #3d3d3d;
+	color: #ffffff;
+	.item {
+		margin-bottom: 5px;
+		border-bottom: 1px solid #ffffff;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		&:last-child {
+			margin-bottom: 0;
+			border-bottom: none;
+		}
+		.left {
+			flex: 1;
+			overflow: hidden;
+		}
+		.right {
+			width: 60px;
+			/deep/ .ivu-btn-primary {
+				background-color: rgb(204, 228, 255);
+			}
+		}
+		.row {
+			margin-bottom: 5px;
+			word-break: break-all;
+		}
+	}
+}
+</style>

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä