Commit eddd577d79a2199853f14dfd7a1a3f6ecded57d4

Authored by xcq
1 parent dee99599

快速出库功能实现

ant-design-vue-jeecg/src/api/api.js
... ... @@ -262,6 +262,8 @@ export const quickReceipt = (params) => postAction("/task/taskHeader/quickReceip
262 262 export const shipmentInventoryHeader = (params) => postAction('/inventory/inventoryHeader/shipmentInventoryHeader', params);
263 263 //快速出库,批量快速出库存详情
264 264 export const shipmentInventoryDetail = (params) => postAction('/inventory/inventoryHeader/shipmentInventoryDetail', params);
  265 +// 快速出库,通过库存ID
  266 +export const autoShipmentByID = (params) => postAction('/shipment/shipmentHeader/autoShipmentByID', params);
265 267 //呼叫入库托盘
266 268 export const callReceiptBox = (params) => postAction('/receipt/receiptHeader/callbox', params);
267 269 //批量呼叫入库托盘
... ... @@ -304,6 +306,8 @@ export const batchCreateCheckOut = (params) => postAction('/task/taskHeader/batc
304 306 export const addInventoryDetail = (params) => postAction('/inventory/inventoryDetail/addInventoryDetail', params);
305 307 //扣减库存数量
306 308 export const reduceInventoryDetail = (params) => postAction('/inventory/inventoryDetail/reduceInventoryDetail', params);
  309 +// 根据库位编码查询库存详情
  310 +export const getInventoryDetailByLocationCode = (params) => getAction('/inventory/inventoryDetail/list', params);
307 311  
308 312 // 中转HTTP请求
309 313 export const transitRESTful = {
... ...
ant-design-vue-jeecg/src/views/system/monitor/locationStatus.vue
1 1 <template>
  2 + <a-card :bordered="false">
2 3 <div class="container-div">
3 4 <div class="row">
4 5 <div class="col-sm-12 select-info">
... ... @@ -30,6 +31,12 @@
30 31 <li>
31 32 <a-button type="primary" @click="Search()" icon="search">查询</a-button>
32 33 </li>
  34 + <li>
  35 + <a-button @click='expressDelivery()' v-if="this.visible" type='primary'>快速出库</a-button>
  36 + </li>
  37 + <li>
  38 + <a-button @click="quickReceipt()" type="primary">快速入库</a-button>
  39 + </li>
33 40 </ul>
34 41 </div>
35 42 </form>
... ... @@ -78,6 +85,10 @@
78 85  
79 86 </div>
80 87 </div>
  88 +
  89 + <MaterialTaskModal ref="materialTaskModal" @ok="modalFormOk"></MaterialTaskModal>
  90 + <ExpressDeliveryModal ref="ExpressDeliveryModal" @ok="modalFormOk"></ExpressDeliveryModal>
  91 + </a-card>
81 92 </template>
82 93  
83 94 <script>
... ... @@ -119,16 +130,29 @@ import grid_all_lock from &#39;@/assets/icon/grid_all_lock.png&#39;
119 130 import rel_empty from '@/assets/icon/rel_empty.png'
120 131 import Vue from 'vue'
121 132 import {ACCESS_TOKEN} from "@/store/mutation-types"
122   -import {getZoneList} from '@/api/api'
  133 +import {getInventoryDetailByLocationCode, getZoneList} from '@/api/api'
  134 +import MaterialTaskModal from "../task/modules/MaterialTaskModal";
  135 +import ExpressDeliveryModal from "@views/system/monitor/modules/ExpressDeliveryModal";
  136 +import {JeecgListMixin} from '@/mixins/JeecgListMixin'
  137 +
123 138  
124 139 export default {
125 140 name: "locationStatus",
126 141 zoneCode: "",
  142 + // parameter:{
  143 + // code:'',
  144 + // } ,
  145 + mixins: [JeecgListMixin],
  146 + components: {
  147 + MaterialTaskModal,
  148 + ExpressDeliveryModal
  149 + },
127 150 data() {
128 151 return {
129 152 spinning: true,
130 153 loading: true,
131 154 showPrise: false,
  155 + visible: false,
132 156 // loading:true,
133 157 zoneCode: '',
134 158 zoneList: [],
... ... @@ -301,7 +325,45 @@ export default {
301 325 return ""
302 326 }
303 327 },
  328 + // 快速入库
  329 + quickReceipt(){
  330 + this.$refs.materialTaskModal.edit();
  331 + },
  332 + // 获取库存信息
  333 + getInventory(locationCode){
  334 + let params = {
  335 + locationCode: locationCode
  336 + }
  337 + getInventoryDetailByLocationCode(params).then((res) => {
  338 + if (res.success) {
  339 + let parameter = [];
  340 + let newArr = res.result.records;
  341 + for(var i of newArr){
  342 + var param = {
  343 + materialCode: i.materialCode,
  344 + shipQty: i.qty,
  345 + inventoryDetailId: i.id,
  346 + }
  347 + parameter.push(param);
  348 + }
  349 + this.$refs.ExpressDeliveryModal.edit(parameter);
  350 + } else {
  351 + this.$message.error(res.message);
  352 + }
  353 + });
  354 + },
  355 + //快速出库
  356 + expressDelivery(){
  357 + this.getInventory(currentLocationCode);
304 358  
  359 + },
  360 + revealExpressDelivery(code, materialCode){
  361 + if (materialCode){
  362 + this.visible = true;
  363 + }else {
  364 + this.visible = false;
  365 + }
  366 + },
305 367  
306 368 //关闭tips
307 369 Mclose(x) {
... ... @@ -481,6 +543,7 @@ export default {
481 543 if (list_info) {//缓存查询
482 544 for (let i = 0; i < list_info.length; i++) {
483 545 if (list_info[i].row === row && list_info[i].icolumn === line && list_info[i].layer === layers) {
  546 + let materialCode = '';
484 547 if (list_info[i].materialName) {
485 548 let list_batch = '';
486 549 let list_qty = 0;
... ... @@ -494,6 +557,7 @@ export default {
494 557 $("#material").append("<option>" + str_info + "</option>");
495 558 }
496 559 currentMaterialCode = list_info[i].materialCode[j]
  560 + materialCode = list_info[i].materialCode[j];
497 561 }
498 562 } else {
499 563 $("#material").children().remove();
... ... @@ -503,6 +567,8 @@ export default {
503 567 $("#containerCode").val(list_info[i].containerCode === "" ? "无" : list_info[i].containerCode);
504 568 currentContainerCode = $("#containerCode").val()
505 569 currentLocationCode = $("#code").val()
  570 + this.revealExpressDelivery(list_info[i].code,materialCode);
  571 + break;
506 572 }
507 573 }
508 574 } else {
... ...
ant-design-vue-jeecg/src/views/system/monitor/modules/ExpressDeliveryModal.vue 0 → 100644
  1 +<template>
  2 + <a-modal
  3 + :title="title"
  4 + :width="800"
  5 + :visible="visible"
  6 + :maskClosable="false"
  7 + :confirmLoading="confirmLoading"
  8 + @ok="handleOk"
  9 + @cancel="handleCancel">
  10 +
  11 + <a-spin :spinning="confirmLoading">
  12 + <a-form-model ref="form" :label-col="labelCol" :wrapper-col="wrapperCol" :model="model">
  13 + <a-tabs defaultActiveKey="1">
  14 + <a-tab-pane tab="物料信息" key="1">
  15 + <div>
  16 + <a-row type="flex" style="margin-bottom:10px" :gutter="24">
  17 + <a-col :span="12">物料编码</a-col>
  18 + <a-col :span="8">数量</a-col>
  19 + <a-col :span="4">操作</a-col>
  20 + </a-row>
  21 + <a-row type="flex" style="margin-bottom:-20px" :gutter="24" v-for="(item, index) in quickMainModel.receiptEntityList" :key="index">
  22 + <a-col style="display: none">
  23 + <a-form-model-item>
  24 + <a-input placeholder="inventoryDetailId" v-model="item.inventoryDetailId"/>
  25 + </a-form-model-item>
  26 + </a-col>
  27 + <a-col :span="12">
  28 + <a-form-model-item>
  29 + <j-search-select-tag
  30 + :disabled="isSearch"
  31 + placeholder="请选择"
  32 + v-model="item.materialCode"
  33 + :dict="'material,name,code'"
  34 + :pageSize="5"
  35 + :async="true">
  36 + </j-search-select-tag>
  37 + </a-form-model-item>
  38 + </a-col>
  39 + <a-col :span="8">
  40 + <a-form-model-item>
  41 + <a-input placeholder="数量" v-model="item.shipQty"/>
  42 + </a-form-model-item>
  43 + </a-col>
  44 + <a-col :span="4">
  45 + <a-form-model-item>
  46 + <a-icon type="minus-circle" @click="delRowCustom(index)" style="fontSize :20px"/>
  47 + </a-form-model-item>
  48 + </a-col>
  49 + </a-row>
  50 +<!-- <a-button type="dashed" style="width: 100%;margin-top: 10px" @click="addRowCustom"><a-icon type="plus"/>添加出库信息</a-button>-->
  51 + </div>
  52 + </a-tab-pane>
  53 + </a-tabs>
  54 + </a-form-model>
  55 + </a-spin>
  56 + </a-modal>
  57 +</template>
  58 +
  59 +<script>
  60 +
  61 +import JEditableTable from '@/components/jeecg/JEditableTable'
  62 +import {execute, autoShipmentByID} from '@/api/api'
  63 +import JDate from '@/components/jeecg/JDate'
  64 +import JSelectMultiCanUseContainer from "../../../../components/jeecgbiz/JSelectMultiCanUseContainer";
  65 +
  66 +
  67 +export default {
  68 + name: 'ExpressDeliveryModal',
  69 + components: {
  70 + JDate, JEditableTable,JSelectMultiCanUseContainer
  71 + },
  72 + data() {
  73 + return {
  74 + title: '快速出库',
  75 + visible: false,
  76 + confirmLoading: false,
  77 + model: {},
  78 + isSearch:true,
  79 + labelCol: {
  80 + xs: {span: 24},
  81 + sm: {span: 4}
  82 + },
  83 + wrapperCol: {
  84 + xs: {span: 24},
  85 + sm: {span: 24}
  86 + },
  87 + activeKey: '1',
  88 + quickMainModel: {
  89 + receiptEntityList: [{}],
  90 + inventoryDetailList: []
  91 + },
  92 + // 客户信息
  93 + url: {
  94 + add: '/test/jeecgOrderMain/add',
  95 + edit: '/test/jeecgOrderMain/edit',
  96 + }
  97 + }
  98 + },
  99 + created() {
  100 + },
  101 + methods: {
  102 + handleOk() {
  103 + this.validateFields()
  104 + },
  105 + handleCancel() {
  106 + this.visible = false
  107 + },
  108 +
  109 + addRowCustom() {
  110 + this.quickMainModel.receiptEntityList.push({});
  111 + this.$forceUpdate();
  112 + },
  113 + delRowCustom(index) {
  114 + console.log(index)
  115 + this.quickMainModel.receiptEntityList.splice(index, 1);
  116 + this.$forceUpdate();
  117 + },
  118 + addRowTicket() {
  119 + this.quickMainModel.jeecgOrderTicketList.push({});
  120 + console.log(this.quickMainModel.jeecgOrderTicketList)
  121 + this.$forceUpdate();
  122 + },
  123 + delRowTicket(index) {
  124 + console.log(index)
  125 + this.quickMainModel.jeecgOrderTicketList.splice(index, 1);
  126 + this.$forceUpdate();
  127 + },
  128 +
  129 + edit(record) {
  130 + this.visible = true;
  131 + this.activeKey = '1';
  132 + this.quickMainModel = Object.assign({
  133 + receiptEntityList: record
  134 + }, record);
  135 + },
  136 + /** 触发表单验证 */
  137 + validateFields() {
  138 + // 触发表单验证
  139 + this.$refs.form.validate(valid => {
  140 + this.receipt(this.quickMainModel);
  141 + })
  142 + },
  143 +
  144 + receipt(record) {
  145 + debugger
  146 + this.confirmLoading = true
  147 + this.model = Object.assign({}, record);
  148 + autoShipmentByID(record.receiptEntityList).then((res) => {
  149 + this.loading = false;
  150 + if (res.success) {
  151 + this.$message.success(res.message);
  152 + this.$emit('ok');
  153 + this.visible = false
  154 + } else {
  155 + this.$message.error(res.message);
  156 + }
  157 + this.confirmLoading = false
  158 + });
  159 + },
  160 + }
  161 +}
  162 +</script>
0 163 \ No newline at end of file
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/service/IHuahengMultiHandlerService.java
... ... @@ -8,6 +8,7 @@ import org.jeecg.modules.wms.api.mobile.entity.QuickReceiptBean;
8 8 import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerHeader;
9 9 import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptHeader;
10 10 import org.jeecg.modules.wms.shipment.shipmentCombination.entity.CombinationModel;
  11 +import org.jeecg.modules.wms.shipment.shipmentCombination.entity.FlatShipment;
11 12 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
12 13 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.CombinationParam;
13 14 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
... ... @@ -54,4 +55,9 @@ public interface IHuahengMultiHandlerService {
54 55  
55 56 void sendTaskToWcs(List<TaskHeader> taskHeaders, String warehouseCode, String zoneCode);
56 57  
  58 + /**
  59 + * 通过详情ID查询库存详情
  60 + */
  61 + Result autoShipmentByIDService(List<FlatShipment> flatShipmentList, String warehouseCode);
  62 +
57 63 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/service/impl/HuahengMultiHandlerServiceImpl.java
1 1 package org.jeecg.modules.wms.framework.service.impl;
2 2  
3 3 import java.math.BigDecimal;
  4 +import java.util.ArrayList;
4 5 import java.util.List;
  6 +import java.util.Map;
  7 +import java.util.function.Function;
  8 +import java.util.stream.Collectors;
5 9  
6 10 import javax.annotation.Resource;
7 11  
... ... @@ -18,6 +22,8 @@ import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContai
18 22 import org.jeecg.modules.wms.receipt.receiptContainerHeader.service.IReceiptContainerHeaderService;
19 23 import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptHeader;
20 24 import org.jeecg.modules.wms.shipment.shipmentCombination.entity.CombinationModel;
  25 +import org.jeecg.modules.wms.shipment.shipmentCombination.entity.FlatShipment;
  26 +import org.jeecg.modules.wms.shipment.shipmentCombination.entity.Shipment;
21 27 import org.jeecg.modules.wms.shipment.shipmentCombination.service.IShipmentCombinationService;
22 28 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
23 29 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerHeaderService;
... ... @@ -28,10 +34,12 @@ import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailServ
28 34 import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService;
29 35 import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader;
30 36 import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService;
  37 +import org.jeecg.utils.constant.QuantityConstant;
31 38 import org.springframework.scheduling.annotation.Async;
32 39 import org.springframework.stereotype.Service;
33 40  
34 41 import lombok.extern.slf4j.Slf4j;
  42 +import org.springframework.transaction.annotation.Transactional;
35 43  
36 44 /**
37 45 * @author 游杰
... ... @@ -67,6 +75,7 @@ public class HuahengMultiHandlerServiceImpl extends HuahengBaseController implem
67 75 @Resource
68 76 private IErpService erpService;
69 77  
  78 +
70 79 @Override
71 80 public Result sendTaskToWcs(TaskHeader taskHeader, String zoneCode) {
72 81 if (taskHeader == null) {
... ... @@ -104,6 +113,63 @@ public class HuahengMultiHandlerServiceImpl extends HuahengBaseController implem
104 113 }
105 114  
106 115 @Override
  116 + @Transactional(rollbackFor = Exception.class)
  117 + public Result autoShipmentByIDService(List<FlatShipment> flatShipmentList, String warehouseCode) {
  118 + // 校验库存id参数
  119 + if (flatShipmentList == null || flatShipmentList.size() == 0) {
  120 + return Result.error("参数不能为空");
  121 + }
  122 + for (FlatShipment item :flatShipmentList){
  123 + if (item.getInventoryDetailId() == null) {
  124 + return Result.error("库存ID不能为空");
  125 + }
  126 + if (item.getShipQty() == null || item.getShipQty().compareTo(BigDecimal.ZERO) == 0){
  127 + return Result.error("出库数量不能为空");
  128 + }
  129 + }
  130 + // 通过库存ID查询库存详情数据
  131 + List<InventoryDetail> inventoryDetailList = inventoryDetailService.listByIds(flatShipmentList.stream().map(FlatShipment::getInventoryDetailId).collect(Collectors.toList()));
  132 + if (inventoryDetailList == null || inventoryDetailList.size() == 0){
  133 + return Result.error("根据库存ID查询库存信息失败!");
  134 + }
  135 + // 根据库存详情创建出库单
  136 + Map<Integer, InventoryDetail> inventoryDetailMap = inventoryDetailList.stream().collect(Collectors.toMap(InventoryDetail::getId, Function.identity()));
  137 + ShipmentHeader shipmentHeader = new ShipmentHeader();
  138 + shipmentHeader.setWarehouseCode(warehouseCode);
  139 + shipmentHeader.setType(QuantityConstant.SHIPMENT_BILL_TYPE_QTC);
  140 + shipmentHeader.setZoneCode(QuantityConstant.ZONE_TYPE_FLAT);
  141 + shipmentHeader.setCompanyCode(inventoryDetailList.get(0).getCompanyCode());
  142 + Result result = shipmentHeaderService.saveShipmentHeader(shipmentHeader);
  143 + if (!result.isSuccess()){
  144 + return result;
  145 + }
  146 + List<ShipmentDetail> shipmentDetailList = new ArrayList<>();
  147 + for (FlatShipment item : flatShipmentList){
  148 + InventoryDetail inventoryDetail = inventoryDetailMap.get(item.getInventoryDetailId());
  149 + ShipmentDetail shipmentDetail = new ShipmentDetail();
  150 + shipmentDetail.setShipmentId(shipmentHeader.getId());
  151 + shipmentDetail.setQty(item.getShipQty());
  152 + shipmentDetail.setMaterialCode(inventoryDetail.getMaterialCode());
  153 + shipmentDetail.setMaterialName(inventoryDetail.getMaterialName());
  154 + shipmentDetail.setInventoryStatus(inventoryDetail.getInventoryStatus());
  155 + shipmentDetail.setShipmentCode(shipmentHeader.getCode());
  156 + shipmentDetail.setInventoryDetailId(item.getInventoryDetailId());
  157 + shipmentDetail.setCompanyCode(shipmentHeader.getCompanyCode());
  158 + result = shipmentDetailService.saveShipmentDetail(shipmentDetail);
  159 + if (!result.isSuccess()){
  160 + throw new RuntimeException(result.getMessage());
  161 + }
  162 + shipmentDetailList.add(shipmentDetail);
  163 + }
  164 + // 将出库单详情转换为map存储
  165 + Map<Integer, ShipmentDetail> shipmentDetailMap = shipmentDetailList.stream().collect(Collectors.toMap(ShipmentDetail::getInventoryDetailId, Function.identity()));
  166 + for (FlatShipment item : flatShipmentList){
  167 + item.setShipmentDetailId(shipmentDetailMap.get(item.getInventoryDetailId()).getId());
  168 + }
  169 + return shipmentCombinationService.flatShipmentByContainerCode(inventoryDetailList.get(0).getContainerCode(), flatShipmentList, warehouseCode);
  170 + }
  171 +
  172 + @Override
107 173 public Result createReceiptTask(ReceiptContainerHeader receiptContainerHeader, String warehouseCode) {
108 174 Result result = handleMultiProcess("createReceiptTask", warehouseCode, new MultiProcessListener() {
109 175 @Override
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/entity/FlatShipment.java
... ... @@ -14,5 +14,6 @@ public class FlatShipment {
14 14 private String locationCode;
15 15 private Integer shipmentDetailId;
16 16 private BigDecimal shipQty;
  17 + private Integer inventoryDetailId;
17 18  
18 19 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/controller/ShipmentHeaderController.java
... ... @@ -25,6 +25,7 @@ import org.jeecg.modules.wms.api.mobile.service.IMobileService;
25 25 import org.jeecg.modules.wms.framework.service.IHuahengMultiHandlerService;
26 26 import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
27 27 import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryDetailService;
  28 +import org.jeecg.modules.wms.shipment.shipmentCombination.entity.FlatShipment;
28 29 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
29 30 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
30 31 import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService;
... ... @@ -413,6 +414,18 @@ public class ShipmentHeaderController extends JeecgController&lt;ShipmentHeader, IS
413 414 return result;
414 415 }
415 416  
  417 + /**
  418 + * 平库出库,通过库存ID
  419 + * @return
  420 + */
  421 + @AutoLog(value = "平库出库,通过库存ID")
  422 + @ApiOperation(value = "平库出库,通过库存ID", notes = "平库出库,通过库存ID")
  423 + @PostMapping("/autoShipmentByID")
  424 + public Result autoShipmentByID(@RequestBody List<FlatShipment> flatShipmentList, HttpServletRequest req){
  425 + String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req);
  426 + return huahengMultiHandlerService.autoShipmentByIDService(flatShipmentList, warehouseCode);
  427 + }
  428 +
416 429 @AutoLog(value = "自动预配盘出库")
417 430 @ApiOperation(value = "自动预配盘出库", notes = "自动预配盘出库")
418 431 @PostMapping("/autoShipmentAdvice")
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/entity/ShipmentDetail.java
... ... @@ -150,6 +150,8 @@ public class ShipmentDetail implements Serializable {
150 150 /** 更新日期 */
151 151 @ApiModelProperty(value = "更新日期")
152 152 private Date updateTime;
  153 + @TableField(exist = false)
  154 + private Integer inventoryDetailId;
153 155  
154 156 public void setQty(BigDecimal qty) {
155 157 if (qty.compareTo(BigDecimal.ZERO) <= 0) {
... ...
huaheng-wms-core/src/main/resources/application-test.yml
... ... @@ -165,9 +165,9 @@ spring:
165 165 #redis 配置
166 166 redis:
167 167 database: 0
168   - host: 172.16.29.77
  168 + host: 127.0.0.1
169 169 port: 6379
170   - password: 123456
  170 + password: ''
171 171 timeout: 5000 #超时时间ms
172 172 lettuce:
173 173 pool:
... ... @@ -306,8 +306,8 @@ jeecg:
306 306 data-type: database
307 307 #分布式锁配置
308 308 redisson:
309   - address: 172.16.29.77:6379
310   - password: 123456
  309 + address: 127.0.0.1:6379
  310 + password: ''
311 311 type: STANDALONE
312 312 enabled: true
313 313 #cas单点登录
... ...