diff --git a/ant-design-vue-jeecg/src/api/api.js b/ant-design-vue-jeecg/src/api/api.js
index 398aef9..5b2b068 100644
--- a/ant-design-vue-jeecg/src/api/api.js
+++ b/ant-design-vue-jeecg/src/api/api.js
@@ -330,6 +330,8 @@ export const queryInventoryDetailListByMainIds = (params) => postAction("/invent
 export const getInventoryByShipmentDetail = (params) => postAction('/shipment/shipmentHeader/getInventoryByShipmentDetail', params);
 //指定库位
 export const allocation = (params) => postAction('/receipt/receiptContainerHeader/allocation', params);
+//添加BOM
+export const addBomHeader = (params) => postAction('/config/bomHeader/addBomHeader', params);
 
 // 中转HTTP请求
 export const transitRESTful = {
diff --git a/ant-design-vue-jeecg/src/views/system/shipment/ShipmentDetailList.vue b/ant-design-vue-jeecg/src/views/system/shipment/ShipmentDetailList.vue
index fd3be84..e1362e1 100644
--- a/ant-design-vue-jeecg/src/views/system/shipment/ShipmentDetailList.vue
+++ b/ant-design-vue-jeecg/src/views/system/shipment/ShipmentDetailList.vue
@@ -3,6 +3,7 @@
     <!-- 操作按钮区域 -->
     <div class="table-operator" v-if="mainId">
       <a-button @click="handleAdd" v-has="'shipmentDetail:add'" type="primary" icon="plus">新增</a-button>
+      <a-button @click="handleAddBom()" v-has="'shipmentDetail:addBom'" type="primary" icon="plus">新增BOM</a-button>
       <a-button v-has="'shipmentDetail:print'" @click="batchPrint()" type="primary">打印</a-button>
       <a-button v-has="'shipmentDetail:export'" type="primary" icon="download" @click="handleExportXls('出库单详情')">导出</a-button>
       <a-upload
@@ -72,6 +73,7 @@
     </div>
 
     <shipmentDetail-modal ref="modalForm" @ok="modalFormOk" @dataSearch="dataSearch" :mainId="mainId"></shipmentDetail-modal>
+    <shipment-detail-bom-modal ref="modalBomForm" @ok="modalFormOk" :mainId="mainId"></shipment-detail-bom-modal>
     <shipment-detail-edit-modal ref="modalEditForm" @ok="modalFormOk" @close="searchQuery" :mainId="mainId"></shipment-detail-edit-modal>
     <shipment-detail-combine-modal ref="modalCombineForm" @ok="modalFormOk" @close="searchQuery" :mainId="mainId"></shipment-detail-combine-modal>
 
@@ -84,11 +86,12 @@ import {JeecgListMixin} from '@/mixins/JeecgListMixin'
 import ShipmentDetailModal from './modules/ShipmentDetailModal'
 import ShipmentDetailEditModal from './modules/ShipmentDetailEditModal'
 import ShipmentDetailCombineModal from './modules/ShipmentDetailCombineModal'
+import ShipmentDetailBomModal from "@views/system/shipment/modules/ShipmentDetailBomModal.vue";
 
 export default {
   name: "ShipmentDetailList",
   mixins: [JeecgListMixin],
-  components: {ShipmentDetailCombineModal, ShipmentDetailEditModal, ShipmentDetailModal},
+  components: {ShipmentDetailBomModal, ShipmentDetailCombineModal, ShipmentDetailEditModal, ShipmentDetailModal},
   props: {
     mainId: {
       type: String,
@@ -283,6 +286,11 @@ export default {
         window.open(window._CONFIG['domianURL'] + "/jmreport/view/963962951128367104/?id=" + ids, "newWindow", "toolbar=no,scrollbars=no,menubar=no,screenX=100,screenY=100");
       }
     },
+    handleAddBom() {
+      this.$refs.modalBomForm.add();
+      this.$refs.modalBomForm.title = "新增BOM";
+      this.$refs.modalBomForm.disableSubmit = false;
+    },
     edit(record) {
       this.$refs.modalEditForm.edit(record);
       this.$refs.modalEditForm.title = "编辑";
diff --git a/ant-design-vue-jeecg/src/views/system/shipment/modules/ShipmentDetailBomModal.vue b/ant-design-vue-jeecg/src/views/system/shipment/modules/ShipmentDetailBomModal.vue
new file mode 100644
index 0000000..b8e1aae
--- /dev/null
+++ b/ant-design-vue-jeecg/src/views/system/shipment/modules/ShipmentDetailBomModal.vue
@@ -0,0 +1,135 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    switchFullscreen
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <a-spin :spinning="confirmLoading">
+      <a-form-model ref="form" :model="model" :rules="validatorRules">
+        <a-row>
+          <a-form-model-item label="物料BOM" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="materialCode">
+            <j-search-select-tag
+              placeholder="请选择物料BOM"
+              v-model="model.materialCode"
+              dict="bom_header,material_name,material_code"
+              :pageSize="10"
+              :async="true">
+            </j-search-select-tag>
+          </a-form-model-item>
+          <a-col :span="24">
+            <a-form-model-item label="套数" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="qty">
+              <a-input-number v-model="model.qty" placeholder="请输入套数" style="width: 100%"/>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </a-spin>
+  </j-modal>
+</template>
+
+<script>
+
+import {httpAction} from '@/api/manage'
+import {validateDuplicateValue} from '@/utils/util'
+import {addBomHeader, getInventoryByShipmentDetail, searchMaterialByCode} from '@/api/api'
+
+export default {
+  name: "ShipmentDetailBomModal",
+  components: {},
+  props: {
+    mainId: {
+      type: String,
+      required: false,
+      default: ''
+    }
+  },
+  data() {
+    return {
+      title: "操作",
+      width: 800,
+      visible: false,
+      materialList: {},
+      shipmentDetail: {},
+      querySource: {},
+      model: {},
+      labelCol: {
+        xs: {span: 24},
+        sm: {span: 5},
+      },
+      wrapperCol: {
+        xs: {span: 24},
+        sm: {span: 16},
+      },
+
+      confirmLoading: false,
+      validatorRules: {
+        materialCode: [
+          {required: true, message: '请输入物料编码!'},
+        ],
+        qty: [
+          {required: true, message: '请输入单据数量!'},
+        ],
+        inventoryStatus: [
+          {required: true, message: '请输入库存状态!'},
+        ],
+      },
+      url: {
+        add: "/shipment/shipmentHeader/addShipmentDetail",
+        edit: "/shipment/shipmentHeader/editShipmentDetail",
+      }
+
+    }
+  },
+  created() {
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  methods: {
+    add() {
+      let record={inventoryStatus:'good'}
+      this.edit(record);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      this.visible = true;
+    },
+    close() {
+      this.$emit('close');
+      this.visible = false;
+      this.$refs.form.clearValidate();
+    },
+    handleOk() {
+      const that = this;
+      // 触发表单验证
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          that.confirmLoading = true;
+          this.model['shipmentHeaderId'] = this.mainId
+          addBomHeader(this.model).then((res) => {
+            if (res.success) {
+              that.$message.success(res.message);
+              that.$emit('ok');
+              that.$emit('dataSearch');
+            } else {
+              that.$message.warning(res.message);
+            }
+          }).finally(() => {
+            that.confirmLoading = false;
+            that.close();
+          })
+        } else {
+          return false
+        }
+      })
+    },
+    handleCancel() {
+      this.close()
+    },
+
+  }
+}
+</script>
diff --git a/ant-design-vue-jeecg/src/views/system/stocktaking/CycleCountHeaderList.vue b/ant-design-vue-jeecg/src/views/system/stocktaking/CycleCountHeaderList.vue
index 17baf9c..25b8529 100644
--- a/ant-design-vue-jeecg/src/views/system/stocktaking/CycleCountHeaderList.vue
+++ b/ant-design-vue-jeecg/src/views/system/stocktaking/CycleCountHeaderList.vue
@@ -56,7 +56,7 @@
         :dataSource="dataSource"
         :pagination="ipagination"
         :loading="loading"
-        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type:'radio'}"
         :customRow="clickThenSelect"
         :rowClassName="rowClassName"
         class="j-table-force-nowrap"
@@ -226,6 +226,18 @@ export default {
         exportXlsUrl: '/cycleCountHeader/cycleCountHeader/exportXls',
         importExcelUrl: 'cycleCountHeader/cycleCountHeader/importExcel'
       },
+      /* 分页参数 */
+      ipagination: {
+        current: 1,
+        pageSize: 5,
+        pageSizeOptions: ['5', '10', '50'],
+        showTotal: (total, range) => {
+          return range[0] + "-" + range[1] + " 共" + total + "条"
+        },
+        showQuickJumper: true,
+        showSizeChanger: true,
+        total: 0
+      },
       superFieldList: []
     }
   },
diff --git a/ant-design-vue-jeecg/src/views/system/task/AllTaskHeaderList.vue b/ant-design-vue-jeecg/src/views/system/task/AllTaskHeaderList.vue
index 14c930e..1b221f4 100644
--- a/ant-design-vue-jeecg/src/views/system/task/AllTaskHeaderList.vue
+++ b/ant-design-vue-jeecg/src/views/system/task/AllTaskHeaderList.vue
@@ -170,6 +170,9 @@
           <a-popconfirm v-if="record.status <= 10" v-has="'taskHeader:cancelTask'" title="确定取消任务吗?" @confirm="() => cancelTask(record)">
            <a-button type="danger">取消</a-button>
           </a-popconfirm>
+          <a-popconfirm v-if="record.status <= 10 && record.taskType != 600 " v-has="'taskHeader:switchTask'" title="确定切换任务吗?" @confirm="() => switchTask(record)">
+            <a-button type="danger">切换任务</a-button>
+          </a-popconfirm>
         </span>
 
       </a-table>
@@ -207,7 +210,7 @@ import {getAction} from '@/api/manage'
 import TaskDetailList from './TaskDetailList'
 import {initDictOptions, filterMultiDictText} from '@/components/dict/JDictSelectUtil'
 import '@/assets/less/TableExpand.less'
-import {completeTaskByWMS, cancelTask} from '@/api/api'
+import {completeTaskByWMS, cancelTask, switchTask} from '@/api/api'
 import {execute} from '@/api/api'
 import {getZoneList, handleEmptyOut, handlePickupError, handleDoubleIn} from '@/api/api'
 import EmptyInTaskModal from './modules/EmptyInTaskModal'
@@ -453,6 +456,19 @@ export default {
       this.ipagination = pagination;
       this.loadData();
     },
+    switchTask(record) {
+      this.loading = true;
+      this.model = Object.assign({}, record);
+      switchTask(this.model.id).then((res) => {
+        this.loading = false;
+        if (res.success) {
+          this.$message.success(res.message);
+        } else {
+          this.$message.error(res.message);
+        }
+        this.searchQuery();
+      });
+    },
     getStatusColor(status) {
       const colors = {
         '生成任务': 'green',
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/bomHeader/controller/BomHeaderController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/bomHeader/controller/BomHeaderController.java
index acf8883..37e159d 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/bomHeader/controller/BomHeaderController.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/bomHeader/controller/BomHeaderController.java
@@ -1,6 +1,7 @@
 package org.jeecg.modules.wms.config.bomHeader.controller;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -14,6 +15,7 @@ import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.common.system.base.controller.JeecgController;
 import org.jeecg.common.system.query.QueryGenerator;
 import org.jeecg.common.system.vo.LoginUser;
@@ -24,7 +26,10 @@ import org.jeecg.modules.wms.config.bomHeader.service.IBomDetailService;
 import org.jeecg.modules.wms.config.bomHeader.service.IBomHeaderService;
 import org.jeecg.modules.wms.config.material.entity.Material;
 import org.jeecg.modules.wms.config.material.service.IMaterialService;
+import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
+import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService;
 import org.jeecg.utils.HuahengJwtUtil;
+import org.jeecg.utils.constant.QuantityConstant;
 import org.jeecgframework.poi.excel.ExcelImportUtil;
 import org.jeecgframework.poi.excel.def.NormalExcelConstants;
 import org.jeecgframework.poi.excel.entity.ExportParams;
@@ -36,8 +41,10 @@ import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartHttpServletRequest;
 import org.springframework.web.servlet.ModelAndView;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 
 import io.swagger.annotations.Api;
@@ -65,6 +72,9 @@ public class BomHeaderController extends JeecgController<BomHeader, IBomHeaderSe
     @Resource
     private IMaterialService materialService;
 
+    @Resource
+    private IShipmentDetailService shipmentDetailService;
+
     /*---------------------------------主表处理-begin-------------------------------------*/
 
     /**
@@ -321,4 +331,34 @@ public class BomHeaderController extends JeecgController<BomHeader, IBomHeaderSe
 
     /*--------------------------------子表处理-bom子表-end----------------------------------------------*/
 
+    /**
+     * 添加
+     * @return
+     */
+    @AutoLog(value = "bom子表-添加")
+    @ApiOperation(value = "bom子表-添加", notes = "bom子表-添加")
+    @PostMapping(value = "/addBomHeader")
+    public Result addBomHeader(@RequestBody BomHeader bomHeader, HttpServletRequest req) {
+        String bomCode = bomHeader.getMaterialCode();
+        BigDecimal qty = bomHeader.getQty();
+        int shipmentHeaderId = bomHeader.getShipmentHeaderId();
+        LambdaQueryWrapper<BomHeader> bomHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
+        bomHeaderLambdaQueryWrapper.eq(BomHeader::getMaterialCode, bomCode);
+        BomHeader bomHeader1 = bomHeaderService.getOne(bomHeaderLambdaQueryWrapper);
+        List<BomDetail> bomDetailList = bomDetailService.selectByMainId(String.valueOf(bomHeader1.getId()));
+        for (BomDetail bomDetail : bomDetailList) {
+            ShipmentDetail shipmentDetail = new ShipmentDetail();
+            shipmentDetail.setShipmentId(shipmentHeaderId);
+            shipmentDetail.setMaterialCode(bomDetail.getMaterialCode());
+            shipmentDetail.setInventoryStatus(QuantityConstant.QUALITY_GOOD);
+            BigDecimal bomDetailQty = bomDetail.getQty();
+            bomDetailQty = bomDetailQty.multiply(qty);
+            shipmentDetail.setQty(bomDetailQty);
+            Result result = shipmentDetailService.saveShipmentDetail(shipmentDetail);
+            if (!result.isSuccess()) {
+                throw new JeecgBootException("添加失败," + result.getMessage());
+            }
+        }
+        return Result.OK("添加成功!");
+    }
 }
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/bomHeader/entity/BomHeader.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/bomHeader/entity/BomHeader.java
index 1d96557..47a978f 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/bomHeader/entity/BomHeader.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/bomHeader/entity/BomHeader.java
@@ -76,4 +76,8 @@ public class BomHeader implements Serializable {
     /** 齐套数量 */
     @TableField(exist = false)
     private java.math.BigDecimal completeQty;
+
+    /** 出库单ID */
+    @TableField(exist = false)
+    private Integer shipmentHeaderId;
 }
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java
index 51d4169..d490dc9 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java
@@ -108,8 +108,8 @@ public class LocationServiceImpl extends ServiceImpl<LocationMapper, Location> i
     @Override
     public List<Location> getLocationListByZoneCode(String zoneCode, String warehouseCode) {
         LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
-        locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode).eq(Location::getEnable, QuantityConstant.STATUS_ENABLE).eq(Location::getWarehouseCode,
-            warehouseCode);
+        locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode).eq(Location::getEnable, QuantityConstant.STATUS_ENABLE)
+            .eq(Location::getWarehouseCode, warehouseCode).orderByDesc(Location::getLayer);
         return locationService.list(locationLambdaQueryWrapper);
     }
 
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/entity/InventoryDetail.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/entity/InventoryDetail.java
index ccfa89e..949157a 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/entity/InventoryDetail.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/entity/InventoryDetail.java
@@ -137,6 +137,9 @@ public class InventoryDetail implements Serializable {
     /** 巷道 */
     @ApiModelProperty(value = "巷道")
     private Integer roadWay;
+    /** 内外侧 */
+    @ApiModelProperty(value = "内外侧")
+    private Integer rowFlag;
     /** 备用字段1 */
     @Excel(name = "备用字段1", width = 15)
     @ApiModelProperty(value = "备用字段1")
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/entity/InventoryHeader.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/entity/InventoryHeader.java
index 9023300..b5d4001 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/entity/InventoryHeader.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/entity/InventoryHeader.java
@@ -81,6 +81,9 @@ public class InventoryHeader implements Serializable {
     /** 巷道 */
     @ApiModelProperty(value = "巷道")
     private Integer roadWay;
+    /** 内外侧 */
+    @ApiModelProperty(value = "内外侧")
+    private Integer rowFlag;
     /** 备用字段1 */
     @Excel(name = "备用字段1", width = 15)
     @ApiModelProperty(value = "备用字段1")
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryDetailServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryDetailServiceImpl.java
index 44c3a91..dabab47 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryDetailServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryDetailServiceImpl.java
@@ -508,6 +508,7 @@ public class InventoryDetailServiceImpl extends ServiceImpl<InventoryDetailMappe
             return Result.error("增加库存,没有找到库位" + locationCode);
         }
         Integer roadWay = location.getRoadWay();
+        Integer rowFlag = location.getRowFlag();
         String zoneType = zone.getType();
         InventoryDetail inventoryDetail = new InventoryDetail();
         inventoryDetail.setInventoryHeaderId(inventoryHeader.getId());
@@ -524,6 +525,7 @@ public class InventoryDetailServiceImpl extends ServiceImpl<InventoryDetailMappe
         inventoryDetail.setMaterialUnit(material.getUnit());
         inventoryDetail.setQty(qty);
         inventoryDetail.setRoadWay(roadWay);
+        inventoryDetail.setRowFlag(rowFlag);
         inventoryDetail.setInventoryStatus(QuantityConstant.QUALITY_GOOD);
         inventoryDetail.setReceiptDate(new Date());
         if (!inventoryDetailService.save(inventoryDetail)) {
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryHeaderServiceImpl.java
index 4b6db68..56859ea 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryHeaderServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryHeaderServiceImpl.java
@@ -490,6 +490,7 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe
     }
 
     @Override
+    @Transactional
     public boolean updateInventory(String containerCode, String locationCode, String warehouseCode) {
         InventoryHeader inventoryHeader = inventoryHeaderService.getInventoryHeaderByContainerCode(containerCode, warehouseCode);
         if (inventoryHeader == null) {
@@ -526,6 +527,7 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe
             inventoryDetail1.setZoneCode(zoneCode);
             inventoryDetail1.setZoneType(zoneType);
             inventoryDetail1.setRoadWay(toLocation.getRoadWay());
+            inventoryDetail1.setRowFlag(toLocation.getRowFlag());
             updateInventoryDetailList.add(inventoryDetail1);
         }
         success = inventoryDetailService.updateBatchById(updateInventoryDetailList);
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/monitor/job/AutoTransferTask.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/monitor/job/AutoTransferTask.java
new file mode 100644
index 0000000..0fbea6b
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/monitor/job/AutoTransferTask.java
@@ -0,0 +1,100 @@
+package org.jeecg.modules.wms.monitor.job;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import javax.annotation.Resource;
+
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.modules.wms.api.wcs.service.LocationAllocationService;
+import org.jeecg.modules.wms.config.container.service.IContainerService;
+import org.jeecg.modules.wms.config.location.entity.Location;
+import org.jeecg.modules.wms.config.location.service.ILocationService;
+import org.jeecg.modules.wms.config.parameterConfiguration.service.IParameterConfigurationService;
+import org.jeecg.modules.wms.config.zone.entity.Zone;
+import org.jeecg.modules.wms.config.zone.service.IZoneService;
+import org.jeecg.modules.wms.framework.service.IHuahengMultiHandlerService;
+import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader;
+import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService;
+import org.jeecg.utils.StringUtils;
+import org.jeecg.utils.constant.QuantityConstant;
+import org.quartz.*;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 定时任务
+ * @author 游杰
+ */
+
+@Slf4j
+@PersistJobDataAfterExecution
+@DisallowConcurrentExecution
+public class AutoTransferTask implements Job {
+
+    @Resource
+    private ITaskHeaderService taskHeaderService;
+
+    @Resource
+    private IHuahengMultiHandlerService huahengMultiHandlerService;
+
+    @Resource
+    private IContainerService containerService;
+    @Resource
+    private IParameterConfigurationService parameterConfigurationService;
+
+    private String parameter;
+
+    @Resource
+    private IZoneService zoneService;
+
+    @Resource
+    private ILocationService locationService;
+
+    @Resource
+    private LocationAllocationService locationAllocationService;
+
+    /*
+     * 定时筛选立库区托盘从高库位移动到低库位
+     */
+    @Override
+    public void execute(JobExecutionContext context) throws JobExecutionException {
+        log.info(String.format(" AutoTransferTask 执行任务! 时间:" + DateUtils.getTimestamp()));
+        List<Zone> zoneList = zoneService.getZoneListByType(QuantityConstant.ZONE_TYPE_STEREOSCOPIC, QuantityConstant.DEFAULT_WAREHOUSE);
+        for (Zone zone : zoneList) {
+            String zoneCode = zone.getCode();
+            String warehouseCode = zone.getWarehouseCode();
+            List<Location> locationList = locationService.getLocationListByZoneCode(zoneCode, QuantityConstant.DEFAULT_WAREHOUSE);
+            List<Integer> roadWayList = locationList.stream().map(Location::getRoadWay).distinct().collect(Collectors.toList());
+            for (Integer roadWay : roadWayList) {
+                List<TaskHeader> taskHeaderList = taskHeaderService.getUnCompleteListTaskByRoadWay(roadWay, warehouseCode);
+                if (!taskHeaderList.isEmpty()) {
+                    continue;
+                }
+                List<Location> roadWayLocationList =
+                    locationList.stream().filter(x -> x.getRoadWay().equals(roadWay) && StringUtils.isNotEmpty(x.getContainerCode())).collect(Collectors.toList());
+                String value = parameterConfigurationService.getValueByZoneCode(QuantityConstant.RULE_ALLOCATION, zoneCode);
+                if (StringUtils.isEmpty(value)) {
+                    continue;
+                }
+                int allocationRule = Integer.parseInt(value);
+                Location fromLocation = roadWayLocationList.get(0);
+                int high = fromLocation.getHigh();
+                List<String> locationTypeCodeList = new ArrayList<>();
+                locationTypeCodeList.add(fromLocation.getLocationTypeCode());
+                List<Integer> roadWays = new ArrayList<>();
+                roadWays.add(fromLocation.getRoadWay());
+                String locationCode = locationAllocationService.allocation(allocationRule, locationTypeCodeList, high, zoneCode, roadWays, warehouseCode,
+                    fromLocation.getContainerCode(), null, null, false);
+                if (StringUtils.isEmpty(locationCode)) {
+                    continue;
+                }
+                Location toLocation = locationService.getLocationByCode(locationCode, warehouseCode);
+                if (fromLocation.getLayer() > toLocation.getLayer()) {
+                    taskHeaderService.createTransferTask(fromLocation.getCode(), locationCode, warehouseCode);
+                }
+            }
+        }
+    }
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java
index d5150f1..3729c4d 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java
@@ -285,6 +285,9 @@ public class ReceiptContainerHeaderServiceImpl extends ServiceImpl<ReceiptContai
                 }
             }
         }
+        if (!taskHeaderService.updateTaskRoadWay(containerCode, fromLocationCode, warehouseCode)) {
+            throw new JeecgBootException("创建任务时,更新巷道值失败");
+        }
         LogRecordContext.putVariable("taskHeader", taskHeader);// 操作日志收集
         LogRecordContext.putVariable("receiptContainerDetailList", receiptContainerDetailList);// 操作日志收集
         LogRecordContext.putVariable("extraJsonString1", JSON.toJSONString(receiptContainerDetailList));// 操作日志收集
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/IShipmentCombinationService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/IShipmentCombinationService.java
index ba697dc..636c25c 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/IShipmentCombinationService.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/IShipmentCombinationService.java
@@ -19,6 +19,8 @@ public interface IShipmentCombinationService {
 
     List<InventoryDetail> getInventorys(ShipmentDetail shipmentDetail);
 
+    List<InventoryDetail> groupInventorysByRowFlag(List<InventoryDetail> inventoryDetailList);
+
     List<InventoryDetail> getInventorys(ShipmentDetail shipmentDetail, String containerCode);
 
     List<InventoryDetail> getAllInventorys(ShipmentDetail shipmentDetail);
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java
index fa96d27..73bfb56 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java
@@ -3,6 +3,7 @@ package org.jeecg.modules.wms.shipment.shipmentCombination.service.impl;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -174,10 +175,19 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi
             }
             inventoryDetailList = inventoryDetailList.stream().filter(t -> result.getResult().contains(t.getRoadWay())).collect(Collectors.toList());
         }
+
+        inventoryDetailList = groupInventorysByRowFlag(inventoryDetailList);
         return inventoryDetailList;
     }
 
     @Override
+    public List<InventoryDetail> groupInventorysByRowFlag(List<InventoryDetail> inventoryDetailList) {
+        List<InventoryDetail> inventoryDetails = inventoryDetailList.stream()
+            .sorted(Comparator.comparing(InventoryDetail::getReceiptDate).thenComparing(InventoryDetail::getRowFlag)).collect(Collectors.toList());
+        return inventoryDetails;
+    }
+
+    @Override
     public List<InventoryDetail> getInventorys(ShipmentDetail shipmentDetail, String containerCode) {
         String warehouseCode = shipmentDetail.getWarehouseCode();
         String companyCode = shipmentDetail.getCompanyCode();
@@ -1470,6 +1480,9 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi
         if (!success) {
             throw new JeecgBootException("生成出库任务时, 更新出库组盘头失败");
         }
+        if (!taskHeaderService.updateTaskRoadWay(containerCode, fromLocationCode, warehouseCode)) {
+            throw new JeecgBootException("创建任务时,更新巷道值失败");
+        }
         LogRecordContext.putVariable("taskHeader", taskHeader);// 操作日志收集
         LogRecordContext.putVariable("shipmentContainerDetailList", shipmentContainerDetailList);// 操作日志收集
         LogRecordContext.putVariable("extraJsonString1", JSON.toJSONString(shipmentContainerDetailList));// 操作日志收集
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java
index debe31d..6e990b2 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java
@@ -90,6 +90,8 @@ public interface ITaskHeaderService extends IService<TaskHeader> {
 
     List<TaskHeader> getUnCompleteListTask(String warehouseCode);
 
+    List<TaskHeader> getUnCompleteListTaskByRoadWay(Integer roadWay, String warehouseCode);
+
     /**
      * 完成WMS任务
      * @param  taskId
@@ -392,6 +394,8 @@ public interface ITaskHeaderService extends IService<TaskHeader> {
      */
     boolean combineInventoryDetail(String containerCode, String warehouseCode);
 
+    boolean updateTaskRoadWay(String containerCode, String fromLocationCode, String warehouseCode);
+
     /**
      * 根据任务区分,在生产任务的时候,锁定容器和库位
      * @param
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java
index c75236b..5d832a2 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java
@@ -353,6 +353,9 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
         if (!success) {
             throw new JeecgBootException("创建移库任务时,创建任务失败");
         }
+        if (!taskHeaderService.updateTaskRoadWay(containerCode, fromLocationCode, warehouseCode)) {
+            throw new JeecgBootException("创建任务时,更新巷道值失败");
+        }
         log.info("完成创建移库任务,起始库位" + fromLocationCode + ",目的库位" + toLocationCode);
         return Result.OK("创建移库任务成功", taskHeader);
     }
@@ -705,6 +708,9 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
         taskHeader.setToPortCode(toPortCode);
         taskHeader.setStatus(QuantityConstant.TASK_STATUS_BUILD);
         boolean success = taskHeaderService.save(taskHeader);
+        if (!taskHeaderService.updateTaskRoadWay(containerCode, fromLocationCode, warehouseCode)) {
+            throw new JeecgBootException("创建任务时,更新巷道值失败");
+        }
         log.info("完成创建空托盘组出库任务,容器编码" + containerCode + ",去向位置编码" + toPortCode);
         if (!success) {
             throw new JeecgBootException("创建空托盘组出库任务时,生成任务失败");
@@ -1038,6 +1044,15 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
         return taskHeaderList;
     }
 
+    @Override
+    public List<TaskHeader> getUnCompleteListTaskByRoadWay(Integer roadWay, String warehouseCode) {
+        LambdaQueryWrapper<TaskHeader> taskHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
+        taskHeaderLambdaQueryWrapper.eq(TaskHeader::getRoadWay, roadWay).eq(TaskHeader::getWarehouseCode, warehouseCode).lt(TaskHeader::getStatus,
+            QuantityConstant.TASK_STATUS_COMPLETED);
+        List<TaskHeader> taskHeaderList = taskHeaderService.list(taskHeaderLambdaQueryWrapper);
+        return taskHeaderList;
+    }
+
     /**
      * WMS完成任务
      */
@@ -1264,15 +1279,15 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
         taskHeader.setStatus(QuantityConstant.TASK_STATUS_BUILD);
         taskHeader.setZoneCode(zoneCode);
         boolean success = taskHeaderService.save(taskHeader);
-//        String value = parameterConfigurationService.getValueByCode(QuantityConstant.START_LOCKING_STATION, zoneCode);
-//        if (StringUtils.isNotEmpty(value)) {
-//            int lockStation = Integer.parseInt(value);
-//            if (lockStation == QuantityConstant.START_LOCK_STATION) {
-//                if (!lockStationService.lockStation(toPortCode, warehouseCode)) {
-//                    throw new JeecgBootException("生成入库任务时,站台已经锁定:" + toPortCode);
-//                }
-//            }
-//        }
+        String value = parameterConfigurationService.getValueByCode(QuantityConstant.START_LOCKING_STATION, zoneCode);
+        if (StringUtils.isNotEmpty(value)) {
+            int lockStation = Integer.parseInt(value);
+            if (lockStation == QuantityConstant.START_LOCK_STATION) {
+                if (!lockStationService.lockStation(toPortCode, warehouseCode)) {
+                    throw new JeecgBootException("生成入库任务时,站台已经锁定:" + toPortCode);
+                }
+            }
+        }
         log.info("完成创建空托入库任务");
         if (!success) {
             throw new JeecgBootException("创建空托盘入库时,保存任务失败");
@@ -1327,6 +1342,9 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
         if (!success) {
             throw new JeecgBootException("创建空托盘出库时,保存任务失败");
         }
+        if (!taskHeaderService.updateTaskRoadWay(containerCode, fromLocationCode, warehouseCode)) {
+            throw new JeecgBootException("创建任务时,更新巷道值失败");
+        }
         return Result.OK("创建空托盘出库任务成功");
     }
 
@@ -1958,6 +1976,22 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
         return success;
     }
 
+    @Override
+    public boolean updateTaskRoadWay(String containerCode, String fromLocationCode, String warehouseCode) {
+        TaskHeader taskHeader = taskHeaderService.getUnCompleteTaskByContainerCode(containerCode, warehouseCode);
+        if (taskHeader != null) {
+            Location fromLocation = locationService.getLocationByCode(fromLocationCode, warehouseCode);
+            if (fromLocation != null) {
+                TaskHeader taskHeader1 = new TaskHeader();
+                taskHeader1.setId(taskHeader.getId());
+                taskHeader1.setRoadWay(fromLocation.getRoadWay());
+                boolean success = taskHeaderService.updateById(taskHeader1);
+                return success;
+            }
+        }
+        return true;
+    }
+
     /**
      * 锁定容器和库位分4种情况,入库任务、出库任务、分拣任务、换站任务
      * @param