|
@@ -0,0 +1,216 @@
|
|
|
+## **DFI友通资讯操作站**
|
|
|
+
|
|
|
+#### **项目介绍**
|
|
|
+客户为台湾厂商,通过操作站结合WMS及AGV无人车实现智慧仓储物流系统。
|
|
|
+今年4月开发重构第二个版本,目前已完成。
|
|
|
+
|
|
|
+#### **主要工作**
|
|
|
+负责开发前端操作站界面。
|
|
|
+
|
|
|
+#### **主要功能**
|
|
|
+繁体中文及英语多语言功能,业务功能包括:派單,有單上架,無單上架,揀貨,條碼綁定,貨架報表,盤點等功能。
|
|
|
+其中包括ASRS 防潮柜/线边仓版本。
|
|
|
+
|
|
|
+#### **技术栈**
|
|
|
+Vue2 Vuetify
|
|
|
+RabbitMQ 订阅
|
|
|
+
|
|
|
+#### **预览**
|
|
|
+现场操作视频
|
|
|
+
|
|
|
+[WeChat_20231017211753.mp4](WeChat_20231017211753.mp4 ':include :type=video controls width=100%')
|
|
|
+
|
|
|
+
|
|
|
+派单界面
|
|
|
+![Alt text](image-10.png)
|
|
|
+
|
|
|
+拣货界面
|
|
|
+![Alt text](image-11.png)
|
|
|
+
|
|
|
+上架界面
|
|
|
+![Alt text](image-12.png)
|
|
|
+
|
|
|
+
|
|
|
+#### **代码片段(业务封装类)**
|
|
|
+
|
|
|
+```JavaScript
|
|
|
+import $EventBus from '@/utils/$EventBus'
|
|
|
+
|
|
|
+const NO_ITEM = (text = '', $vuetify) => {
|
|
|
+ let message = $vuetify.lang.t('$vuetify.common.message.no_item')
|
|
|
+ return message + ' ' + text
|
|
|
+}
|
|
|
+const SHELF_FULL = (text = '', $vuetify) => {
|
|
|
+ let message = $vuetify.lang.t('$vuetify.common.message.shelf_full')
|
|
|
+ return message + ' ' + text
|
|
|
+}
|
|
|
+
|
|
|
+const NOT_FOUND_BARCODE = ($vuetify) => {
|
|
|
+ return $vuetify.lang.t('$vuetify.common.message.not_found_barcode')
|
|
|
+}
|
|
|
+
|
|
|
+const NOT_FOUND_ITEM = ($vuetify) => {
|
|
|
+ return $vuetify.lang.t('$vuetify.common.message.not_found_item')
|
|
|
+}
|
|
|
+const NUMBER_OUT = ($vuetify) => {
|
|
|
+ return $vuetify.lang.t('$vuetify.common.message.number_out')
|
|
|
+}
|
|
|
+
|
|
|
+const NOT_FOUND_ORDER = ($vuetify) => {
|
|
|
+ return $vuetify.lang.t('$vuetify.common.message.not_found_order')
|
|
|
+}
|
|
|
+
|
|
|
+const REPEAT_SCAN = ($vuetify) => {
|
|
|
+ return $vuetify.lang.t('$vuetify.common.message.repeat_scan')
|
|
|
+}
|
|
|
+
|
|
|
+//刪除條碼,扣回來
|
|
|
+
|
|
|
+export const deleteBarcodeOutInBin = (barcode, inboundOrderDetail, that) => {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ let hu_idx = that.currentHuList.findIndex((item) => item.HuId === barcode)
|
|
|
+ if (hu_idx < 0) {
|
|
|
+ $EventBus.$emit('MESSAGE_RECEIVE', {
|
|
|
+ text: NOT_FOUND_BARCODE(that.$vuetify),
|
|
|
+ type: 'ErrorMessages'
|
|
|
+ })
|
|
|
+ reject()
|
|
|
+ }
|
|
|
+ let barcodeInfo = that.currentHuList[hu_idx]
|
|
|
+
|
|
|
+ let det_idx = inboundOrderDetail.findIndex((item) => item.Id === barcodeInfo.InboundTaskDetId)
|
|
|
+
|
|
|
+ if (det_idx < 0) {
|
|
|
+ $EventBus.$emit('MESSAGE_RECEIVE', {
|
|
|
+ text: NOT_FOUND_ORDER(that.$vuetify),
|
|
|
+ type: 'ErrorMessages'
|
|
|
+ })
|
|
|
+ reject()
|
|
|
+ }
|
|
|
+ let det = inboundOrderDetail[det_idx]
|
|
|
+ det.EntryQty -= barcodeInfo.Qty
|
|
|
+ that.$set(that.inboundOrderInfo.Details, det_idx, det)
|
|
|
+ that.inboundOrderInfo.SumFinishedQty -= barcodeInfo.Qty
|
|
|
+ that.table.deleteRow(barcodeInfo.HuId)
|
|
|
+ that.currentHuList.splice(hu_idx, 1)
|
|
|
+ resolve(barcodeInfo)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+export const semiProductCartonCheck = (barcodeInfoList, inboundOrderDetail, that) => {
|
|
|
+ let qtys = barcodeInfoList.map((item) => {
|
|
|
+ return item.Qty
|
|
|
+ })
|
|
|
+ let huMaxQty = qtys.reduce((n, m) => n + m)
|
|
|
+ let old_qtys = that.currentHuList.map((item) => {
|
|
|
+ return item.Qty
|
|
|
+ })
|
|
|
+ if (huMaxQty > that.inboundOrderInfo.SumUnfinishedQty) {
|
|
|
+ $EventBus.$emit('MESSAGE_RECEIVE', {
|
|
|
+ text: NUMBER_OUT(that.$vuetify),
|
|
|
+ type: 'ErrorMessages'
|
|
|
+ })
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ inboundOrderDetail = JSON.parse(JSON.stringify(that.inboundOrderDetailsCopy))
|
|
|
+ for (let i = 0; i < inboundOrderDetail.length; i++) {
|
|
|
+ if (inboundOrderDetail[i].EntryQty === inboundOrderDetail[i].Qty) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let j = 0; j < barcodeInfoList.length; j++) {
|
|
|
+ if (inboundOrderDetail[i].ItemCode === barcodeInfoList[j].Item) {
|
|
|
+
|
|
|
+ if (barcodeInfoList[j].Qty > (inboundOrderDetail[i].Qty - inboundOrderDetail[i].EntryQty)) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if (barcodeInfoList[j].InboundTaskDetId) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ inboundOrderDetail[i].EntryQty += barcodeInfoList[j].Qty
|
|
|
+ barcodeInfoList[j].InboundTaskDetId = inboundOrderDetail[i].Id
|
|
|
+
|
|
|
+ if (inboundOrderDetail[i].ErpLoc !== null && inboundOrderDetail[i].ErpLoc !== '') {
|
|
|
+ barcodeInfoList[j].ErpLoc = inboundOrderDetail[i].ErpLoc
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (i === (inboundOrderDetail.length - 1)) {
|
|
|
+ that.itemInfo.item = inboundOrderDetail[i].ItemCode
|
|
|
+ that.itemInfo.qty = inboundOrderDetail[i].Qty
|
|
|
+ that.itemInfo.item_desc = inboundOrderDetail[i].ItemName
|
|
|
+ that.itemInfo.remaining = inboundOrderDetail[i].Qty - inboundOrderDetail[i].EntryQty
|
|
|
+ that.itemInfo.enter_qty = inboundOrderDetail[i].EntryQty
|
|
|
+ }
|
|
|
+ }
|
|
|
+ that.$set(that.inboundOrderInfo, 'Details', inboundOrderDetail)
|
|
|
+ if (old_qtys.length > 0) {
|
|
|
+ that.inboundOrderInfo.SumFinishedQty -= old_qtys.reduce((n, m) => n + m)
|
|
|
+ }
|
|
|
+ that.inboundOrderInfo.SumFinishedQty += qtys.reduce((n, m) => n + m)
|
|
|
+ return true
|
|
|
+}
|
|
|
+
|
|
|
+//條碼邏輯
|
|
|
+export const checkPutInBin = (barcodeInfo, inboundOrderDetail, that) => {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ let hu_idx = that.currentHuList.findIndex((item) => item.HuId === barcodeInfo.HuId)
|
|
|
+ if (hu_idx > -1) {
|
|
|
+ $EventBus.$emit('MESSAGE_RECEIVE', {
|
|
|
+ text: REPEAT_SCAN(that.$vuetify),
|
|
|
+ type: 'ErrorMessages'
|
|
|
+ })
|
|
|
+ reject()
|
|
|
+ }
|
|
|
+
|
|
|
+ let matchId = null
|
|
|
+ let matchItem = null
|
|
|
+ // let itemDet = inboundOrderDetail.filter((item,i) => item.ItemCode === barcodeInfo.Item)
|
|
|
+ let itemDet = []
|
|
|
+ for (let i = 0; i < inboundOrderDetail.length; i++) {
|
|
|
+ if (inboundOrderDetail[i].ItemCode === barcodeInfo.Item) {
|
|
|
+ itemDet.push({
|
|
|
+ index: i,
|
|
|
+ item: inboundOrderDetail[i]
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (itemDet.length === 0) {
|
|
|
+ $EventBus.$emit('MESSAGE_RECEIVE', {
|
|
|
+ text: NO_ITEM(barcodeInfo.HuId, that.$vuetify),
|
|
|
+ type: 'ErrorMessages'
|
|
|
+ })
|
|
|
+ reject()
|
|
|
+ } else {
|
|
|
+ for (let i = 0; i < itemDet.length; i++) {
|
|
|
+ if (!matchId) {
|
|
|
+ if (itemDet[i].item.EntryQty < itemDet[i].item.Qty && (itemDet[i].item.Qty - itemDet[i].item.EntryQty) >= barcodeInfo.Qty) {
|
|
|
+ itemDet[i].item.EntryQty += barcodeInfo.Qty
|
|
|
+ that.$set(that.inboundOrderInfo.Details, itemDet[i].index, itemDet[i].item)
|
|
|
+ //set info
|
|
|
+ that.itemInfo.item = itemDet[i].item.ItemCode
|
|
|
+ that.itemInfo.qty = itemDet[i].item.Qty
|
|
|
+ that.itemInfo.item_desc = itemDet[i].item.ItemName
|
|
|
+ that.itemInfo.remaining = itemDet[i].item.Qty - itemDet[i].item.EntryQty
|
|
|
+ that.itemInfo.enter_qty = itemDet[i].item.EntryQty
|
|
|
+
|
|
|
+ matchId = itemDet[i].item.Id
|
|
|
+ matchItem = itemDet[i].item
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!matchId) {
|
|
|
+ $EventBus.$emit('MESSAGE_RECEIVE', {
|
|
|
+ text: SHELF_FULL(barcodeInfo.HuId, that.$vuetify),
|
|
|
+ type: 'ErrorMessages'
|
|
|
+ })
|
|
|
+ reject()
|
|
|
+ } else {
|
|
|
+ resolve(matchItem)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+```
|