Commit 931c454ff08cc3f2fc3d0acf9678a0526ea2159b

Authored by 易文鹏
1 parent 773f59eb

feat: 完成常用物料优先分配就近库位功能

src/main/java/com/huaheng/api/wcs/controller/EmptyContainerController.java
... ... @@ -81,13 +81,14 @@ public class EmptyContainerController extends BaseController {
81 81  
82 82 /**
83 83 * 生成空托盘组入库任务
  84 + *
84 85 * @return
85 86 */
86 87 @PostMapping("/manyEmptyIn")
87 88 @Log(title = "任务-任务管理", operating = "生成空托盘组入库任务", action = BusinessType.INSERT)
88 89 @ResponseBody
89 90 @Transactional
90   - @ApiLogger(apiName = "manyEmptyIn", from="ROBOT")
  91 + @ApiLogger(apiName = "manyEmptyIn", from = "ROBOT")
91 92 public AjaxResult manyEmptyIn(@RequestBody ManyEmptyDomain manyEmptyDomain) {
92 93 AjaxResult ajaxResult = handleMultiProcess(new MultiProcessListener() {
93 94 @Override
... ... @@ -100,16 +101,16 @@ public class EmptyContainerController extends BaseController {
100 101 }
101 102  
102 103  
103   -
104 104 /**
105 105 * 生成空托盘组出库任务
  106 + *
106 107 * @return
107 108 */
108 109 @PostMapping("/manyEmptyOut")
109 110 @Log(title = "任务-任务管理", operating = "生成空托盘组出库任务", action = BusinessType.INSERT)
110 111 @ResponseBody
111 112 @Transactional
112   - @ApiLogger(apiName = "manyEmptyOut", from="ROBOT")
  113 + @ApiLogger(apiName = "manyEmptyOut", from = "ROBOT")
113 114 public AjaxResult manyEmptyOut(@RequestBody ManyEmptyDomain manyEmptyDomain) {
114 115 AjaxResult ajaxResult = handleMultiProcess(new MultiProcessListener() {
115 116 @Override
... ... @@ -122,7 +123,7 @@ public class EmptyContainerController extends BaseController {
122 123 }
123 124  
124 125 private AjaxResult innerManyEmptyIn(@RequestBody ManyEmptyDomain manyEmptyDomain) {
125   - if(manyEmptyDomain == null){
  126 + if (manyEmptyDomain == null) {
126 127 throw new ServiceException("空托盘组参数不对!");
127 128 }
128 129 String containerCode = manyEmptyDomain.getContainerCode();
... ... @@ -130,7 +131,7 @@ public class EmptyContainerController extends BaseController {
130 131 String area = manyEmptyDomain.getArea();
131 132 String roadWay = manyEmptyDomain.getRoadWay();
132 133 List<String> roadWays = new ArrayList<>();
133   - String[] str= roadWay.split(",");
  134 + String[] str = roadWay.split(",");
134 135 roadWays = Arrays.asList(str);
135 136 String value = configService.getKey(QuantityConstant.RULE_ALLOCATION);
136 137 String height = manyEmptyDomain.getHeight();
... ... @@ -141,7 +142,7 @@ public class EmptyContainerController extends BaseController {
141 142 LambdaQueryWrapper<Zone> zoneLambdaQueryWrapper = Wrappers.lambdaQuery();
142 143 zoneLambdaQueryWrapper.eq(Zone::getArea, area);
143 144 Zone zone = zoneService.getOne(zoneLambdaQueryWrapper);
144   - if(zone == null) {
  145 + if (zone == null) {
145 146 return AjaxResult.error("分配库位时,没有找到库区");
146 147 }
147 148 LambdaQueryWrapper<TaskHeader> taskHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
... ... @@ -149,7 +150,7 @@ public class EmptyContainerController extends BaseController {
149 150 .eq(TaskHeader::getWarehouseCode, warehouseCode)
150 151 .lt(TaskHeader::getStatus, QuantityConstant.TASK_STATUS_COMPLETED);
151 152 TaskHeader taskHeader = taskHeaderService.getOne(taskHeaderLambdaQueryWrapper);
152   - if(taskHeader != null) {
  153 + if (taskHeader != null) {
153 154 return AjaxResult.success("已经生成空托盘组任务");
154 155 }
155 156 //查询满足条件的库位类型
... ... @@ -157,7 +158,7 @@ public class EmptyContainerController extends BaseController {
157 158 lambdaQueryWrapper.eq(LocationType::getZoneCode, zone.getCode())
158 159 .eq(LocationType::getWarehouseCode, warehouseCode);
159 160 List<LocationType> locationTypeList = locationTypeService.list(lambdaQueryWrapper);
160   - if(locationTypeList == null) {
  161 + if (locationTypeList == null) {
161 162 return AjaxResult.error("分配库位时,没有找到库位类型");
162 163 }
163 164 List<String> locationTypeCodeList = locationTypeList.stream().
... ... @@ -169,8 +170,8 @@ public class EmptyContainerController extends BaseController {
169 170 LocationHigh locationHigh = locationHighService.getOne(locationHighLambdaQueryWrapper);
170 171 int high = locationHigh.getHigh();
171 172 String locationCode = allocationService.allocation(allocationRule, locationTypeCodeList, high, area,
172   - roadWays, warehouseCode, containerCode, null);
173   - if(locationCode == null) {
  173 + roadWays, warehouseCode, containerCode, null, 3);
  174 + if (locationCode == null) {
174 175 return AjaxResult.error("分配库位时,没有找到库位");
175 176 }
176 177 return workTaskService.createManyEmptyIn(containerCode, locationCode, warehouseCode);
... ... @@ -178,7 +179,7 @@ public class EmptyContainerController extends BaseController {
178 179  
179 180  
180 181 private AjaxResult innerManyEmptyOut(ManyEmptyDomain manyEmptyDomain) {
181   - if(manyEmptyDomain == null){
  182 + if (manyEmptyDomain == null) {
182 183 throw new ServiceException("空托盘组参数不对!");
183 184 }
184 185 String warehouseCode = manyEmptyDomain.getWarehouseCode();
... ... @@ -189,11 +190,11 @@ public class EmptyContainerController extends BaseController {
189 190 .eq(Container::getWarehouseCode, warehouseCode);
190 191 List<Container> containerList = containerService.list(containerLambdaQueryWrapper);
191 192 List<Container> removeContainerList = new ArrayList<>();
192   - if(containerList != null && containerList.size() > 0) {
193   - for(Container container : containerList) {
  193 + if (containerList != null && containerList.size() > 0) {
  194 + for (Container container : containerList) {
194 195 String locationCode = container.getLocationCode();
195 196 Location location = locationService.getLocationByCode(locationCode, warehouseCode);
196   - if(!location.getArea().equals(area)) {
  197 + if (!location.getArea().equals(area)) {
197 198 removeContainerList.add(container);
198 199 }
199 200 }
... ... @@ -207,7 +208,7 @@ public class EmptyContainerController extends BaseController {
207 208 .eq(TaskHeader::getPort, port)
208 209 .eq(TaskHeader::getZoneCode, zone.getCode());
209 210 TaskHeader taskHeader = taskHeaderService.getOne(taskHeaderLambdaQueryWrapper);
210   - if(taskHeader != null) {
  211 + if (taskHeader != null) {
211 212 WcsTask wcsTask = new WcsTask();
212 213 wcsTask.setTaskType(taskHeader.getTaskType());
213 214 wcsTask.setTaskNo(String.valueOf(taskHeader.getId()));
... ... @@ -222,12 +223,12 @@ public class EmptyContainerController extends BaseController {
222 223 return AjaxResult.success(wcsTask);
223 224 }
224 225 containerList.removeAll(removeContainerList);
225   - if(!(containerList != null && containerList.size() > 0)) {
  226 + if (!(containerList != null && containerList.size() > 0)) {
226 227 return AjaxResult.error("没有找到合适的空托盘组!");
227 228 }
228 229 String containerCode = containerList.get(0).getCode();
229 230 Container container = containerService.getContainerByCode(containerCode, warehouseCode);
230   - if(container == null){
  231 + if (container == null) {
231 232 throw new ServiceException("没有找到托盘“");
232 233 }
233 234 return workTaskService.createManyEmptyOut(containerCode, warehouseCode, port);
... ... @@ -235,12 +236,13 @@ public class EmptyContainerController extends BaseController {
235 236  
236 237 /**
237 238 * 生成空托出库任务
  239 + *
238 240 * @return
239 241 */
240 242 @PostMapping("/wcsCallEmptyOut")
241 243 @Log(title = "任务-任务管理", operating = "生成空托出库任务", action = BusinessType.INSERT)
242 244 @ResponseBody
243   - @ApiLogger(apiName = "生成空托出库任务", from="WCS")
  245 + @ApiLogger(apiName = "生成空托出库任务", from = "WCS")
244 246 public AjaxResult wcsCallEmptyOut(@RequestBody ManyEmptyDomain manyEmptyDomain) {
245 247 AjaxResult ajaxResult = handleMultiProcess(new MultiProcessListener() {
246 248 @Override
... ... @@ -256,26 +258,26 @@ public class EmptyContainerController extends BaseController {
256 258 String warehouseCode = manyEmptyDomain.getWarehouseCode();
257 259 String area = manyEmptyDomain.getArea();
258 260 String port = manyEmptyDomain.getPort();
259   - if(warehouseCode == null) {
  261 + if (warehouseCode == null) {
260 262 return AjaxResult.error("warehouseCode 不能为空");
261 263 }
262   - if(area == null) {
  264 + if (area == null) {
263 265 return AjaxResult.error("area 不能为空");
264 266 }
265   - if(port == null) {
  267 + if (port == null) {
266 268 return AjaxResult.error("port 不能为空");
267 269 }
268 270 LambdaQueryWrapper<Zone> zoneLambdaQueryWrapper = Wrappers.lambdaQuery();
269 271 zoneLambdaQueryWrapper.eq(Zone::getWarehouseCode, warehouseCode)
270 272 .eq(Zone::getArea, area);
271 273 Zone zone = zoneService.getOne(zoneLambdaQueryWrapper);
272   - if(zone == null) {
  274 + if (zone == null) {
273 275 return AjaxResult.error("area不正确,没有找到对应区域");
274 276 }
275 277 String zoneCode = zone.getCode();
276 278 List<Location> list = containerService.getEmptyContainerInLocation(zoneCode,
277   - "","", warehouseCode);
278   - if(list == null || list.size() <= 0) {
  279 + "", "", warehouseCode);
  280 + if (list == null || list.size() <= 0) {
279 281 return AjaxResult.error("没有找到空托盘");
280 282 }
281 283 Location location = list.get(0);
... ...
src/main/java/com/huaheng/api/wcs/service/overrideHandle/OverrideHandleServiceImpl.java
1 1 package com.huaheng.api.wcs.service.overrideHandle;
2 2  
  3 +import cn.hutool.core.util.ObjectUtil;
3 4 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 5 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
5 6 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
... ... @@ -23,6 +24,8 @@ import com.huaheng.pc.config.locationType.domain.LocationType;
23 24 import com.huaheng.pc.config.locationType.service.LocationTypeService;
24 25 import com.huaheng.pc.config.material.domain.Material;
25 26 import com.huaheng.pc.config.material.service.MaterialService;
  27 +import com.huaheng.pc.inventory.inventoryTransaction.domain.vo.InventoryRankVO;
  28 +import com.huaheng.pc.inventory.inventoryTransaction.service.InventoryTransactionService;
26 29 import com.huaheng.pc.receipt.receiptContainerDetail.domain.ReceiptContainerDetail;
27 30 import com.huaheng.pc.receipt.receiptContainerDetail.service.ReceiptContainerDetailService;
28 31 import com.huaheng.pc.receipt.receiptContainerHeader.domain.ReceiptContainerHeader;
... ... @@ -73,6 +76,7 @@ public class OverrideHandleServiceImpl implements OverrideHandleService {
73 76 private ConfigService configService;
74 77 @Resource
75 78 private MaterialService materialService;
  79 +
76 80 /**
77 81 * 重入处理
78 82 * 1、判断非空字段
... ... @@ -87,28 +91,28 @@ public class OverrideHandleServiceImpl implements OverrideHandleService {
87 91 String taskNo = taskFinishDomain.getTaskNo();
88 92  
89 93 //1、判断非空字段
90   - if(StringUtils.isEmpty(taskNo)) {
  94 + if (StringUtils.isEmpty(taskNo)) {
91 95 return AjaxResult.error("任务号为空");
92 96 }
93 97  
94 98 //2、根据任务号查找任务
95 99 TaskHeader taskHeader = taskHeaderService.getById(taskNo);
96   - if(taskHeader == null){
  100 + if (taskHeader == null) {
97 101 return AjaxResult.error("任务号错误,没有找到该任务");
98 102 }
99 103 String warehouseCode = taskHeader.getWarehouseCode();
100 104 int status = taskHeader.getStatus();
101   - if(status == QuantityConstant.TASK_STATUS_COMPLETED) {
  105 + if (status == QuantityConstant.TASK_STATUS_COMPLETED) {
102 106 return AjaxResult.error("任务已完成");
103 107 }
104 108  
105 109 //3、修改任务目的库位,修改入库组盘的库位,修改库位状态
106 110 //修改原来目的库位的状态
107 111 LambdaQueryWrapper<Location> locationLam = Wrappers.lambdaQuery();
108   - locationLam.eq(Location::getCode,taskHeader.getToLocation())
  112 + locationLam.eq(Location::getCode, taskHeader.getToLocation())
109 113 .eq(Location::getWarehouseCode, warehouseCode);
110 114 Location location = locationService.getOne(locationLam);
111   - if(location == null) {
  115 + if (location == null) {
112 116 return AjaxResult.error("此任务的原目的库位在系统中不存在");
113 117 }
114 118 /**
... ... @@ -124,7 +128,7 @@ public class OverrideHandleServiceImpl implements OverrideHandleService {
124 128 int allocationRule = Integer.parseInt(value);
125 129 List<String> locationTypeCodeList = new ArrayList<>();
126 130 String locationType = location.getLocationType();
127   - if(StringUtils.isNotEmpty(locationType)) {
  131 + if (StringUtils.isNotEmpty(locationType)) {
128 132 locationTypeCodeList.add(locationType);
129 133 }
130 134 int high = location.getHigh();
... ... @@ -135,13 +139,19 @@ public class OverrideHandleServiceImpl implements OverrideHandleService {
135 139 String containerCode = taskHeader.getContainerCode();
136 140 List<TaskDetail> taskDetailList = taskDetailService.findByTaskId(taskHeader.getId());
137 141 String materialAreaCode = null;
138   - if(taskDetailList != null && taskDetailList.size() > 0) {
  142 + if (taskDetailList != null && taskDetailList.size() > 0) {
139 143 String materialCode = taskDetailList.get(0).getMaterialCode();
140 144 Material material = materialService.getMaterialByCode(materialCode, warehouseCode);
141 145 materialAreaCode = material.getMaterialAreaCode();
142 146 }
  147 +
  148 + //根据任务明细计算出分配哪个常用库区
  149 + int frequencyLocation = 3;
  150 + if (taskDetailList != null) {
  151 + frequencyLocation = computeFrequencyLocation(taskDetailList);
  152 + }
143 153 String locationCode = locationAllocationService.allocation(allocationRule,
144   - locationTypeCodeList, high, area, roadWays, warehouseCode, containerCode, materialAreaCode);
  154 + locationTypeCodeList, high, area, roadWays, warehouseCode, containerCode, materialAreaCode, frequencyLocation);
145 155 if (StringUtils.isEmpty(locationCode)) {
146 156 return AjaxResult.error("没有库位可分配");
147 157 }
... ... @@ -150,7 +160,7 @@ public class OverrideHandleServiceImpl implements OverrideHandleService {
150 160 taskType == QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT) {
151 161 //查询入库组盘明细
152 162 List<ReceiptContainerDetail> receiptContainerDetailList = new ArrayList<>();
153   - if(taskDetailList != null) {
  163 + if (taskDetailList != null) {
154 164 for (TaskDetail taskDetail : taskDetailList) {
155 165 receiptContainerDetailList.add(receiptContainerDetailService.
156 166 getById(taskDetail.getAllocationId()));
... ... @@ -178,25 +188,25 @@ public class OverrideHandleServiceImpl implements OverrideHandleService {
178 188 taskHeader.setExceptionCode("重入处理");
179 189 taskHeader.setIsDoubleIn(QuantityConstant.DOUBLE_IN);
180 190 String originLocationCode = taskHeader.getOriginLocation();
181   - if(StringUtils.isEmpty(originLocationCode)) {
  191 + if (StringUtils.isEmpty(originLocationCode)) {
182 192 taskHeader.setOriginLocation(toLocationCode);
183 193 }
184   - if(!taskHeaderService.updateById(taskHeader)){
  194 + if (!taskHeaderService.updateById(taskHeader)) {
185 195 throw new ServiceException("修改此任务错误");
186 196 }
187 197  
188 198 //修改子任务
189 199 LambdaQueryWrapper<TaskDetail> taskDetailLam = Wrappers.lambdaQuery();
190 200 taskDetailLam.eq(TaskDetail::getWarehouseCode, warehouseCode)
191   - .eq(TaskDetail::getTaskId,taskHeader.getId());
  201 + .eq(TaskDetail::getTaskId, taskHeader.getId());
192 202 List<TaskDetail> taskDetails = taskDetailService.list(taskDetailLam);
193 203 taskDetailList = new ArrayList<>();
194   - if(taskDetails != null && taskDetails.size()> 0) {
195   - for(TaskDetail taskDetail : taskDetails){
  204 + if (taskDetails != null && taskDetails.size() > 0) {
  205 + for (TaskDetail taskDetail : taskDetails) {
196 206 taskDetail.setToLocation(newLocationCode);
197 207 taskDetailList.add(taskDetail);
198 208 }
199   - if(!taskDetailService.updateBatchById(taskDetailList)) {
  209 + if (!taskDetailService.updateBatchById(taskDetailList)) {
200 210 throw new ServiceException("修改此任务的明细错误");
201 211 }
202 212 }
... ... @@ -206,4 +216,30 @@ public class OverrideHandleServiceImpl implements OverrideHandleService {
206 216 map.put("taskNo", String.valueOf(taskHeader.getId()));
207 217 return AjaxResult.success("重入处理成功").setData(map);
208 218 }
  219 +
  220 + private int computeFrequencyLocation(List<TaskDetail> taskDetailList) {
  221 + // 判断是否存在top30排行物料
  222 + Map<String, InventoryRankVO> top30 = inventoryTransactionService.getMaterialDetailByKey(INVENTORY_RANKING_TOP_30_KEY);
  223 + for (TaskDetail taskDetail : taskDetailList) {
  224 + InventoryRankVO inputMaterialCode = top30.get(taskDetail.getMaterialCode());
  225 + if (ObjectUtil.isNotEmpty(inputMaterialCode)) {
  226 + return 1;
  227 + }
  228 + }
  229 + // 判断是否存在top31-100排行物料
  230 + Map<String, InventoryRankVO> top70 = inventoryTransactionService.getMaterialDetailByKey(INVENTORY_RANKING_TOP_70_KEY);
  231 + for (TaskDetail taskDetail : taskDetailList) {
  232 + InventoryRankVO inputMaterialCode = top70.get(taskDetail.getMaterialCode());
  233 + if (ObjectUtil.isNotEmpty(inputMaterialCode)) {
  234 + return 2;
  235 + }
  236 + }
  237 + return 3;
  238 + }
  239 +
  240 + @Resource
  241 + private InventoryTransactionService inventoryTransactionService;
  242 +
  243 + private final static String INVENTORY_RANKING_TOP_30_KEY = "INVENTORY_RANKING_TOP_30";
  244 + private final static String INVENTORY_RANKING_TOP_70_KEY = "INVENTORY_RANKING_TOP_70";
209 245 }
... ...
src/main/java/com/huaheng/api/wcs/service/warecellAllocation/LocationAllocationService.java
... ... @@ -7,8 +7,7 @@ import java.util.List;
7 7 public interface LocationAllocationService {
8 8  
9 9  
10   - String allocation(int locationRule, List<String> locationTypeCodeList, int high, String area,
11   - List<String> roadWay, String warehouseCode, String containerCode,
12   - String materialAreaCode);
13   -
  10 + String allocation(int locationRule, List<String> locationTypeCodeList, int high, String area,
  11 + List<String> roadWay, String warehouseCode, String containerCode,
  12 + String materialAreaCode, Integer frequencyLocation);
14 13 }
... ...
src/main/java/com/huaheng/api/wcs/service/warecellAllocation/LocationAllocationServiceImpl.java
... ... @@ -50,46 +50,45 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
50 50 @Override
51 51 public String allocation(int locationRule, List<String> locationTypeCodeList,
52 52 int high, String area, List<String> raodWays, String warehouseCode,
53   - String containerCode, String materialAreaCode) {
54   - LambdaQueryWrapper<Container> containerLambdaQueryWrapper = Wrappers.lambdaQuery();
55   - containerLambdaQueryWrapper.eq(Container::getCode, containerCode)
56   - .eq(Container::getWarehouseCode, warehouseCode);
57   - Container container = containerService.getOne(containerLambdaQueryWrapper);
  53 + String containerCode, String materialAreaCode, Integer frequencyLocation) {
  54 + //容器对象
  55 + Container container = containerService.getOne(new LambdaQueryWrapper<Container>()
  56 + .eq(Container::getCode, containerCode)
  57 + .eq(Container::getWarehouseCode, warehouseCode));
  58 +
  59 + //容器类型
  60 + ContainerType containerType = containerTypeService.getOne(new LambdaQueryWrapper<ContainerType>()
  61 + .eq(ContainerType::getCode, container.getContainerType())
  62 + .eq(ContainerType::getWarehouseCode, warehouseCode));
58 63  
59   - LambdaQueryWrapper<ContainerType> containerTypeLambdaQueryWrapper = Wrappers.lambdaQuery();
60   - containerTypeLambdaQueryWrapper.eq(ContainerType::getCode, container.getContainerType())
61   - .eq(ContainerType::getWarehouseCode, warehouseCode);
62   - ContainerType containerType = containerTypeService.getOne(containerTypeLambdaQueryWrapper);
63 64 List<LocationType> locationTypeList = new ArrayList<>();
64 65 if (containerType != null) {
65 66 String locationType = containerType.getLocationType();
66 67 String[] list = locationType.split(",");
67 68 for (String str : list) {
68   - LambdaQueryWrapper<LocationType> locationTypeLambdaQueryWrapper = Wrappers.lambdaQuery();
69   - locationTypeLambdaQueryWrapper.eq(LocationType::getWarehouseCode, warehouseCode)
70   - .eq(LocationType::getCode, str);
71   - LocationType locationType1 = locationTypeService.getOne(locationTypeLambdaQueryWrapper);
  69 + //根据容器类型查询对应库位类型
  70 + LocationType locationType1 = locationTypeService.getOne(new LambdaQueryWrapper<LocationType>()
  71 + .eq(LocationType::getWarehouseCode, warehouseCode)
  72 + .eq(LocationType::getCode, str));
72 73 locationTypeList.add(locationType1);
73 74 }
74 75 } else {
75   - LambdaQueryWrapper<Zone> zoneLambdaQueryWrapper = Wrappers.lambdaQuery();
76   - zoneLambdaQueryWrapper.eq(Zone::getWarehouseCode, warehouseCode)
77   - .eq(Zone::getArea, area);
78   - Zone zone = zoneService.getOne(zoneLambdaQueryWrapper);
  76 + //如果容器类型位空
  77 + Zone zone = zoneService.getOne(new LambdaQueryWrapper<Zone>()
  78 + .eq(Zone::getWarehouseCode, warehouseCode)
  79 + .eq(Zone::getArea, area));
79 80 if (zone != null) {
80   - LambdaQueryWrapper<LocationType> locationTypeLambdaQueryWrapper = Wrappers.lambdaQuery();
81   - locationTypeLambdaQueryWrapper.eq(LocationType::getWarehouseCode, warehouseCode)
82   - .eq(LocationType::getZoneCode, zone.getCode());
83   - locationTypeList = locationTypeService.list(locationTypeLambdaQueryWrapper);
  81 + locationTypeList = locationTypeService.list(new LambdaQueryWrapper<LocationType>()
  82 + .eq(LocationType::getWarehouseCode, warehouseCode)
  83 + .eq(LocationType::getZoneCode, zone.getCode()));
84 84 }
85 85 }
86 86  
87   - List<String> locationTypeCodes = locationTypeList.stream().
88   - map(t -> t.getCode()).collect(toList());
89   - List<String> mergelocationTypeCodeList = locationTypeCodeList.stream().filter(item -> locationTypeCodes.contains(item)).collect(toList());
  87 + List<String> locationTypeCodes = locationTypeList.stream().map(LocationType::getCode).collect(toList());
  88 + List<String> mergelocationTypeCodeList = locationTypeCodeList.stream().filter(locationTypeCodes::contains).collect(toList());
90 89 switch (locationRule) {
91 90 case QuantityConstant.DOUBLE_FORK:
92   - return doubleRk(area, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode);
  91 + return doubleRk(area, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode, frequencyLocation);
93 92 case QuantityConstant.SINGLE_FORK:
94 93 return singleRk(area, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode);
95 94 }
... ... @@ -99,25 +98,22 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
99 98 /**
100 99 * 双伸位库位入库分配库位
101 100 */
102   - private String doubleRk(String area, List<String> roadWays, int high, String warehouseCode,
103   - List<String> locationTypeCodeList, String materialAreaCode) {
104   - if (roadWays == null || roadWays.size() < 1) {
105   - LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
106   - locationLambdaQueryWrapper.eq(Location::getArea, area);
107   - List<Location> locationList = locationService.list(locationLambdaQueryWrapper);
  101 + private String doubleRk(String area, List<String> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode, Integer frequencyLocation) {
  102 + //巷道为空的话
  103 + if (roadWays == null || roadWays.isEmpty()) {
  104 + List<Location> locationList = locationService.list(new LambdaQueryWrapper<Location>().eq(Location::getArea, area));
108 105 roadWays = locationList.stream().map(Location::getRoadway).distinct().collect(toList());
109 106 }
  107 + //双伸位预留库位数
110 108 String value = configService.getKey(QuantityConstant.DOUBLE_FORK_RESERVE_LOCATION);
111 109 int reserveNumber = 0;
112 110 if (StringUtils.isNotEmpty(value)) {
113 111 reserveNumber = Integer.parseInt(value);
114 112 }
115   - StopWatch stopWatch = new StopWatch();
116   - stopWatch.start("aaa");
117 113 List<String> removeRoadWays = new ArrayList<>();
118 114 for (String roadWay : roadWays) {
119   - LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
120   - locationLambdaQueryWrapper.eq(Location::getArea, area).
  115 + LambdaQueryWrapper<Location> wrapper = Wrappers.lambdaQuery();
  116 + wrapper.eq(Location::getArea, area).
121 117 eq(Location::getWarehouseCode, warehouseCode)
122 118 .eq(StringUtils.isNotEmpty(roadWay), Location::getRoadway, roadWay)
123 119 .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
... ... @@ -127,20 +123,19 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
127 123 .eq(Location::getContainerCode, "")
128 124 .orderByAsc(Location::getILayer)
129 125 .last(" limit 20");
130   - List<Location> totalLocationList = locationService.list(locationLambdaQueryWrapper);
  126 + List<Location> totalLocationList = locationService.list(wrapper);
  127 + //双伸位预留库位数不够了就删掉
131 128 if (totalLocationList.size() <= reserveNumber) {
132 129 removeRoadWays.add(roadWay);
133 130 }
134 131 }
135   - stopWatch.stop();
136   - System.out.println("waste aa:" + stopWatch.getLastTaskTimeMillis());
137   - stopWatch.start("bbb");
138 132 roadWays.removeAll(removeRoadWays);
139 133 Collections.shuffle(roadWays);
140   - if (roadWays.size() == 0) {
  134 + if (roadWays.isEmpty()) {
141 135 return "可能是双伸位巷道保留库位数不够了";
142 136 }
143 137 String roadWay = roadWays.get(0);
  138 + //查外侧的库位
144 139 LambdaQueryWrapper<Location> locationLambda = Wrappers.lambdaQuery();
145 140 locationLambda.eq(Location::getArea, area).
146 141 eq(Location::getWarehouseCode, warehouseCode)
... ... @@ -148,24 +143,37 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
148 143 .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY)
149 144 .eq(Location::getHigh, high)
150 145 .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode)
151   - .eq(Location::getRowFlag, QuantityConstant.ROW_OUT)
  146 + .eq(Location::getRowFlag, QuantityConstant.ROW_OUT)//外侧
152 147 .in(Location::getLocationType, locationTypeCodeList)
153 148 .eq(Location::getContainerCode, "")
154   - .orderByAsc(Location::getILayer)
155 149 .last(" limit 20");
  150 + //频繁
  151 + if (frequencyLocation == 1) {
  152 + locationLambda.orderByAsc(Location::getFrequencyLocation); //升序
  153 + } else if (frequencyLocation == 2) {
  154 + //常用
  155 + locationLambda.ge(Location::getFrequencyLocation, 2);//大于等于2
  156 + locationLambda.orderByAsc(Location::getFrequencyLocation);
  157 + } else {
  158 + //不常用
  159 + locationLambda.orderByDesc(Location::getFrequencyLocation);//倒序
  160 + }
  161 + locationLambda.orderByAsc(Location::getILayer);
156 162 List<Location> locationList = locationService.list(locationLambda);
157 163 List<Location> removeLocaationList = new ArrayList<>();
158   - if (locationList != null && locationList.size() > 0) {
  164 + if (locationList != null && !locationList.isEmpty()) {
159 165 for (Location location1 : locationList) {
  166 + //库位内侧,有未完成的任务就去掉这个库位
160 167 if (taskHeaderService.getUncompleteTaskInNear(location1) > 0) {
161 168 removeLocaationList.add(location1);
162 169 }
163 170 }
164 171 }
165   - locationList.removeAll(removeLocaationList);
166   - stopWatch.stop();
167   - System.out.println("waste bb:" + stopWatch.getLastTaskTimeMillis());
168   - if (locationList == null || locationList.size() == 0) {
  172 + if (locationList != null) {
  173 + locationList.removeAll(removeLocaationList);
  174 + }
  175 + //如果没有外侧库位可分配了,再查内侧的库位
  176 + if (locationList == null || locationList.isEmpty()) {
169 177 locationLambda = Wrappers.lambdaQuery();
170 178 locationLambda.eq(Location::getArea, area).
171 179 eq(Location::getWarehouseCode, warehouseCode)
... ... @@ -176,26 +184,37 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
176 184 .eq(Location::getRowFlag, QuantityConstant.ROW_IN)
177 185 .in(Location::getLocationType, locationTypeCodeList)
178 186 .eq(Location::getContainerCode, "")
179   - .orderByAsc(Location::getILayer)
180 187 .last(" limit 20");
181   - ;
  188 + //频繁
  189 + if (frequencyLocation == 1) {
  190 + locationLambda.orderByAsc(Location::getFrequencyLocation); //升序
  191 + } else if (frequencyLocation == 2) {
  192 + //常用
  193 + locationLambda.ge(Location::getFrequencyLocation, 2);//大于等于2
  194 + locationLambda.orderByAsc(Location::getFrequencyLocation);
  195 + } else {
  196 + //不常用
  197 + locationLambda.orderByDesc(Location::getFrequencyLocation);//倒序
  198 + }
  199 + locationLambda.orderByAsc(Location::getILayer);
182 200 locationList = locationService.list(locationLambda);
183 201 removeLocaationList = new ArrayList<>();
184   - if (locationList != null && locationList.size() > 0) {
  202 + if (locationList != null && !locationList.isEmpty()) {
185 203 for (Location location1 : locationList) {
186 204 if (taskHeaderService.getUncompleteTaskInNear(location1) > 0) {
187 205 removeLocaationList.add(location1);
188 206 }
189 207 }
190 208 }
191   - locationList.removeAll(removeLocaationList);
  209 + if (locationList != null) {
  210 + locationList.removeAll(removeLocaationList);
  211 + }
192 212 }
193   - if (locationList == null || locationList.size() == 0) {
  213 + if (locationList == null || locationList.isEmpty()) {
194 214 return null;
195 215 }
196 216 Location location = locationList.stream().findFirst().orElse(null);
197   - String locationCode = location.getCode();
198   - return locationCode;
  217 + return location.getCode();
199 218 }
200 219  
201 220 /**
... ... @@ -225,8 +244,7 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
225 244 if (location == null) {
226 245 return null;
227 246 }
228   - String locationCode = location.getCode();
229   - return locationCode;
  247 + return location.getCode();
230 248 }
231 249  
232 250 }
... ...
src/main/java/com/huaheng/api/wcs/service/warecellAllocation/WarecellAllocationServiceImpl.java
... ... @@ -151,10 +151,7 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService
151 151 if (roadWays == null) {
152 152 return AjaxResult.error("分配库位时,没有获取到可用巷道");
153 153 }
154   -
155   - LambdaQueryWrapper<Zone> zoneLambdaQueryWrapper = Wrappers.lambdaQuery();
156   - zoneLambdaQueryWrapper.eq(Zone::getArea, area);
157   - Zone zone = zoneService.getOne(zoneLambdaQueryWrapper);
  154 + Zone zone = zoneService.getOne(new LambdaQueryWrapper<Zone>().eq(Zone::getArea, area));
158 155 if (zone == null) {
159 156 return AjaxResult.error("分配库位时,没有找到库区");
160 157 }
... ... @@ -172,25 +169,20 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService
172 169 return AjaxResult.error("分配库位时,任务托盘为空");
173 170 }
174 171 //查询满足条件的库位类型
175   - LambdaQueryWrapper<LocationType> lambdaQueryWrapper = Wrappers.lambdaQuery();
176   - lambdaQueryWrapper.eq(LocationType::getZoneCode, zone.getCode())
177   - .eq(LocationType::getWarehouseCode, warehouseCode);
178   - List<LocationType> locationTypeList = locationTypeService.list(lambdaQueryWrapper);
  172 + List<LocationType> locationTypeList = locationTypeService.list(new LambdaQueryWrapper<LocationType>()
  173 + .eq(LocationType::getZoneCode, zone.getCode())
  174 + .eq(LocationType::getWarehouseCode, warehouseCode));
179 175 if (locationTypeList == null) {
180 176 return AjaxResult.error("分配库位时,没有找到库位类型");
181 177 }
182   - List<String> locationTypeCodeList = locationTypeList.stream().
183   - map(t -> t.getCode()).collect(Collectors.toList());
  178 + List<String> locationTypeCodeList = locationTypeList.stream().map(LocationType::getCode).collect(Collectors.toList());
184 179 int highHeight = Float.valueOf(height).intValue();
185   - LambdaQueryWrapper<LocationHigh> locationHighLambdaQueryWrapper = Wrappers.lambdaQuery();
186   - locationHighLambdaQueryWrapper.eq(LocationHigh::getHighLevel, highHeight)
187   - .in(LocationHigh::getLocationTypeCode, locationTypeCodeList);
188   - LocationHigh locationHigh = locationHighService.getOne(locationHighLambdaQueryWrapper);
  180 + LocationHigh locationHigh = locationHighService.getOne(new LambdaQueryWrapper<LocationHigh>()
  181 + .eq(LocationHigh::getHighLevel, highHeight)
  182 + .in(LocationHigh::getLocationTypeCode, locationTypeCodeList));
189 183 int high = locationHigh.getHigh();
190 184 //查询任务明细
191   - LambdaQueryWrapper<TaskDetail> taskDetailLambda = Wrappers.lambdaQuery();
192   - taskDetailLambda.eq(TaskDetail::getTaskId, taskNo);
193   - List<TaskDetail> taskDetailList = taskDetailService.list(taskDetailLambda);
  185 + List<TaskDetail> taskDetailList = taskDetailService.list(new LambdaQueryWrapper<TaskDetail>().eq(TaskDetail::getTaskId, taskNo));
194 186 String value = configService.getKey(QuantityConstant.RULE_ALLOCATION);
195 187 if (StringUtils.isEmpty(value)) {
196 188 return AjaxResult.error("未绑定定位规则");
... ... @@ -222,12 +214,21 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService
222 214 passLimit = false;
223 215 }
224 216  
  217 +
225 218 // TODO inputOrOutPutMaterialcode
226   - locationCode = getNearestLocation(high, "", warehouseCode, "");
227   - if (StrUtil.isBlank(locationCode)) {
228   - locationCode = locationAllocationService.allocation(allocationRule,
229   - locationTypeCodeList, high, area, roadWays, warehouseCode, containerCode, materialAreaCode);
230   - }
  219 + //locationCode = getNearestLocation(high, "", warehouseCode, "");
  220 + //if (StrUtil.isBlank(locationCode)) {
  221 + // locationCode = locationAllocationService.allocation(allocationRule,locationTypeCodeList, high, area, roadWays, warehouseCode, containerCode, materialAreaCode);
  222 + //}
  223 +
  224 +
  225 + //根据任务明细计算出分配哪个常用库区
  226 + int frequencyLocation = computeFrequencyLocation(taskDetailList);
  227 +
  228 + //分配库位
  229 + locationCode = locationAllocationService.allocation(allocationRule, locationTypeCodeList, high, area,
  230 + roadWays, warehouseCode, containerCode, materialAreaCode, frequencyLocation);
  231 +
231 232 if (StringUtils.isEmpty(locationCode)) {
232 233 return AjaxResult.error("没有库位可分配");
233 234 } else if (locationCode.length() > 15) {
... ... @@ -288,8 +289,7 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService
288 289 if (destinationLocation == null) {
289 290 throw new ServiceException("创建移库任务失败, 目标库位为空");
290 291 }
291   - AjaxResult ajaxResult = transferTaskService.createTransferTask(insideLocation.getCode(),
292   - destinationLocation.getCode(), warehouseCode);
  292 + AjaxResult ajaxResult = transferTaskService.createTransferTask(insideLocation.getCode(), destinationLocation.getCode(), warehouseCode);
293 293 preTaskNo = (Integer) ajaxResult.getData();
294 294 if (ajaxResult.hasErr()) {
295 295 throw new ServiceException("创建移库任务失败");
... ... @@ -318,10 +318,31 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService
318 318 return AjaxResult.success().setData(wcsTask1);
319 319 }
320 320  
  321 + private int computeFrequencyLocation(List<TaskDetail> taskDetailList) {
  322 + // 判断是否存在top30排行物料
  323 + Map<String, InventoryRankVO> top30 = inventoryTransactionService.getMaterialDetailByKey(INVENTORY_RANKING_TOP_30_KEY);
  324 + for (TaskDetail taskDetail : taskDetailList) {
  325 + InventoryRankVO inputMaterialCode = top30.get(taskDetail.getMaterialCode());
  326 + if (ObjectUtil.isNotEmpty(inputMaterialCode)) {
  327 + return 1;
  328 + }
  329 + }
  330 + // 判断是否存在top31-100排行物料
  331 + Map<String, InventoryRankVO> top70 = inventoryTransactionService.getMaterialDetailByKey(INVENTORY_RANKING_TOP_70_KEY);
  332 + for (TaskDetail taskDetail : taskDetailList) {
  333 + InventoryRankVO inputMaterialCode = top70.get(taskDetail.getMaterialCode());
  334 + if (ObjectUtil.isNotEmpty(inputMaterialCode)) {
  335 + return 2;
  336 + }
  337 + }
  338 + return 3;
  339 + }
  340 +
321 341 @Resource
322 342 private InventoryTransactionService inventoryTransactionService;
323 343  
324   - private final static String INVENTORY_RANKING_KEY = "INVENTORY_RANKING";
  344 + private final static String INVENTORY_RANKING_TOP_30_KEY = "INVENTORY_RANKING_TOP_30";
  345 + private final static String INVENTORY_RANKING_TOP_70_KEY = "INVENTORY_RANKING_TOP_70";
325 346  
326 347 /**
327 348 * 统计物料出入库的频率,将常用的物料优先分配离出入口近的库区A
... ... @@ -336,7 +357,7 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService
336 357 String warehouseCode,
337 358 String inputOrOutPutMaterialcode) {
338 359 Map<String, InventoryRankVO> inventoryRankMap =
339   - inventoryTransactionService.getMaterialDetailByKey(INVENTORY_RANKING_KEY);
  360 + inventoryTransactionService.getMaterialDetailByKey(INVENTORY_RANKING_TOP_30_KEY);
340 361 InventoryRankVO inputMaterialCode = inventoryRankMap.get(inputOrOutPutMaterialcode);
341 362 // 判断是否存在排行物料
342 363 if (ObjectUtil.isNotEmpty(inputMaterialCode)) {
... ...
src/main/java/com/huaheng/common/constant/QuantityConstant.java
... ... @@ -435,8 +435,9 @@ public class QuantityConstant {
435 435 //非空货架
436 436 public static final Integer POINTS_SOME = 1;
437 437  
438   - public static final int ROW_OUT = 1;
439   - public static final int ROW_IN = 0;
  438 + //内外侧库位
  439 + public static final int ROW_OUT = 1;//外侧
  440 + public static final int ROW_IN = 0;//内侧
440 441  
441 442 //WCS任务下发
442 443 public static final String ADDRESS_WCS_TASK_ASSIGN = "WCS_TASK_ASSIGN";
... ...
src/main/java/com/huaheng/pc/config/location/controller/LocationController.java
... ... @@ -22,7 +22,9 @@ import com.huaheng.pc.config.container.service.ContainerService;
22 22 import com.huaheng.pc.config.location.domain.Location;
23 23 import com.huaheng.pc.config.location.domain.LocationStatus;
24 24 import com.huaheng.pc.config.location.service.LocationService;
  25 +import com.huaheng.pc.config.material.domain.Material;
25 26 import com.huaheng.pc.config.material.service.MaterialService;
  27 +import com.huaheng.pc.config.materialType.domain.MaterialType;
26 28 import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail;
27 29 import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService;
28 30 import com.huaheng.pc.monitor.idle.domain.LocationIdle;
... ... @@ -100,7 +102,9 @@ public class LocationController extends BaseController {
100 102 .eq(StringUtils.isNotNull(location.getIGrid()), Location::getIGrid, location.getIGrid())
101 103 .eq(StringUtils.isNotNull(location.getILayer()), Location::getILayer, location.getILayer())
102 104 .eq(StringUtils.isNotEmpty(location.getStatus()), Location::getStatus, location.getStatus())
  105 + .eq(location.getRowFlag() != null && location.getRowFlag() != -1, Location::getRowFlag, location.getRowFlag())
103 106 .eq(StringUtils.isNotEmpty(location.getLocationType()), Location::getLocationType, location.getLocationType())
  107 + .eq(location.getFrequencyLocation() != null && location.getFrequencyLocation() != -1, Location::getFrequencyLocation, location.getFrequencyLocation())
104 108 .eq(Location::getDeleted, false);
105 109  
106 110 if (StringUtils.isNotEmpty(location.getUserDef2())) {
... ... @@ -399,4 +403,28 @@ public class LocationController extends BaseController {
399 403 return getDataTable(list);
400 404 }
401 405 }
  406 +
  407 +
  408 + /**
  409 + * 批量选择常用库位
  410 + */
  411 + @GetMapping("/selectFrequencyLocation/{ids}")
  412 + public String editSelectType(@PathVariable("ids") String ids, ModelMap mmap) {
  413 + mmap.put("ids", ids);
  414 + return prefix + "/selectFrequencyLocation";
  415 + }
  416 +
  417 + /**
  418 + * 批量选择常用库位,保存
  419 + */
  420 + @ApiOperation(value = "批量选择常用库位,保存", notes = "批量选择常用库位,保存", httpMethod = "POST")
  421 + //@RequiresPermissions("config:material:edit")
  422 + @PostMapping("/selectFrequencyLocation")
  423 + @ResponseBody
  424 + public AjaxResult selectFrequencyLocation(String ids, String type) {
  425 + String[] idArray = Convert.toStrArray(ids);
  426 + LambdaUpdateWrapper<Location> wrapper = Wrappers.lambdaUpdate();
  427 + wrapper.in(Location::getId, idArray).set(Location::getFrequencyLocation, type);
  428 + return toAjax(locationService.update(wrapper));
  429 + }
402 430 }
... ...
src/main/java/com/huaheng/pc/config/location/domain/Location.java
... ... @@ -14,7 +14,7 @@ public class Location implements Serializable {
14 14 /**
15 15 * ID
16 16 */
17   - @TableId(value = "id", type = IdType.AUTO)
  17 + @TableId(value = "id", type = IdType.AUTO)
18 18 private Integer id;
19 19  
20 20 /**
... ... @@ -216,8 +216,11 @@ public class Location implements Serializable {
216 216  
217 217 @TableField(exist = false)
218 218 private List<BigDecimal> qty;
219   - // 打印机名称 标识
220   - // private static final String printName = "Bar Code Printer T-4503E";
  219 + // 打印机名称 标识
  220 + // private static final String printName = "Bar Code Printer T-4503E";
221 221  
222 222 private static final long serialVersionUID = 1L;
  223 +
  224 + @TableField(value = "frequencyLocation")
  225 + private Integer frequencyLocation;
223 226 }
... ...
src/main/java/com/huaheng/pc/config/material/service/MaterialService.java
... ... @@ -11,10 +11,11 @@ import com.huaheng.pc.inventory.inventoryTransaction.domain.InventoryTransaction
11 11 import java.util.List;
12 12 import java.util.Map;
13 13  
14   -public interface MaterialService extends IService<Material>{
  14 +public interface MaterialService extends IService<Material> {
15 15  
16 16 /**
17 17 * 批量删除物料
  18 + *
18 19 * @param ids
19 20 * @return
20 21 */
... ... @@ -22,15 +23,17 @@ public interface MaterialService extends IService&lt;Material&gt;{
22 23  
23 24 /**
24 25 * excel导入物料
  26 + *
25 27 * @param materialList
26 28 * @param updateSupport
27 29 * @param operName
28 30 * @return
29 31 */
30   - String importMaterial(List<Material> materialList, Boolean updateSupport,String operName);
  32 + String importMaterial(List<Material> materialList, Boolean updateSupport, String operName);
31 33  
32 34 /**
33 35 * 添加物料
  36 + *
34 37 * @param material
35 38 * @return
36 39 */
... ... @@ -44,6 +47,7 @@ public interface MaterialService extends IService&lt;Material&gt;{
44 47  
45 48 /**
46 49 * 获得物料联想词
  50 + *
47 51 * @param code
48 52 * @return
49 53 */
... ... @@ -51,6 +55,7 @@ public interface MaterialService extends IService&lt;Material&gt;{
51 55  
52 56 /**
53 57 * 通过物料编码集查询物料的外形编码
  58 + *
54 59 * @param materialCodeList
55 60 * @return
56 61 */
... ... @@ -58,18 +63,24 @@ public interface MaterialService extends IService&lt;Material&gt;{
58 63  
59 64 /**
60 65 * 统计物料排行
  66 + *
61 67 * @param materialCode
62 68 * @param createdBegin
63 69 * @param createdEnd
64 70 * @return
65 71 */
66   - QueryWrapper<InventoryTransaction> inventoryTurnoverAnalysis(String type ,String materialCode, String createdBegin, String createdEnd);
  72 + QueryWrapper<InventoryTransaction> inventoryTurnoverAnalysis(String type, String materialCode, String createdBegin, String createdEnd);
67 73  
68 74 /**
69 75 * 物料日期统计排行
  76 + *
70 77 * @param createdBegin
71 78 * @param createdEnd
72 79 * @return
73 80 */
74   - QueryWrapper<InventoryTransaction> inventoryCreatedAnalysis(String type ,String createdBegin, String createdEnd);
  81 + QueryWrapper<InventoryTransaction> inventoryCreatedAnalysis(String type, String createdBegin, String createdEnd);
  82 +
  83 + //统计物料出入库次数
  84 + QueryWrapper<InventoryTransaction> statisticsMaterialCodeCount(String type, String materialCode, String createdBegin, String createdEnd);
  85 +
75 86 }
... ...
src/main/java/com/huaheng/pc/config/material/service/MaterialServiceImpl.java
... ... @@ -34,7 +34,7 @@ import java.util.regex.Pattern;
34 34 import java.util.stream.Collectors;
35 35  
36 36 @Service
37   -public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> implements MaterialService{
  37 +public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> implements MaterialService {
38 38  
39 39 @Resource
40 40 private ReceiptDetailService receiptDetailService;
... ... @@ -61,28 +61,28 @@ public class MaterialServiceImpl extends ServiceImpl&lt;MaterialMapper, Material&gt; i
61 61 .last("LIMIT 1");
62 62 Map<String, Object> map = receiptDetailService.getMap(lambda);
63 63 if (map != null) {
64   - return AjaxResult.error("物料编码(" + material.getCode() +")存在入库单,不能删除!");
  64 + return AjaxResult.error("物料编码(" + material.getCode() + ")存在入库单,不能删除!");
65 65 }
66 66 material.setDeleted(true);
67 67 material.setLastUpdatedBy(ShiroUtils.getName());
68   - if (this.updateById(material)){
  68 + if (this.updateById(material)) {
69 69 count++;
70 70 }
71 71 }
72   - return AjaxResult.success("成功删除"+count+"条记录");
  72 + return AjaxResult.success("成功删除" + count + "条记录");
73 73 }
74 74  
75 75 /**
76 76 * 导入物料数据
77 77 *
78   - * @param materialList 用户数据列表
79   - * @param operName 操作用户
  78 + * @param materialList 用户数据列表
  79 + * @param operName 操作用户
80 80 * @return 结果
81 81 */
82 82 @Override
83 83 public String importMaterial(List<Material> materialList, Boolean isUpdateSupport, String operName) {
84 84 if (StringUtils.isNull(materialList) || materialList.size() == 0) {
85   - throw new BusinessException("导入数据不能为空!");
  85 + throw new BusinessException("导入数据不能为空!");
86 86 }
87 87 int successNum = 0;
88 88 int failureNum = 0;
... ... @@ -120,6 +120,7 @@ public class MaterialServiceImpl extends ServiceImpl&lt;MaterialMapper, Material&gt; i
120 120  
121 121 /**
122 122 * 添加物料
  123 + *
123 124 * @param material
124 125 * @return
125 126 */
... ... @@ -142,7 +143,7 @@ public class MaterialServiceImpl extends ServiceImpl&lt;MaterialMapper, Material&gt; i
142 143 lambdaQueryWrapper.eq(MaterialUnit::getMaterialCode, material.getCode())
143 144 .eq(MaterialUnit::getUnit, material.getUnit());
144 145 //如果不存在该物料的单位是新建物料单位
145   - if (materialUnitService.getOne(lambdaQueryWrapper) == null){
  146 + if (materialUnitService.getOne(lambdaQueryWrapper) == null) {
146 147 MaterialUnit materialUnit = new MaterialUnit();
147 148 materialUnit.setMaterialCode(material.getCode());
148 149 materialUnit.setMaterialName(material.getName());
... ... @@ -158,8 +159,8 @@ public class MaterialServiceImpl extends ServiceImpl&lt;MaterialMapper, Material&gt; i
158 159 material.setWarehouseCode(ShiroUtils.getWarehouseCode());
159 160 material.setCreatedBy(ShiroUtils.getName());
160 161 material.setLastUpdatedBy(ShiroUtils.getName());
161   - Boolean flag=this.save(material);
162   - if(flag==false){
  162 + Boolean flag = this.save(material);
  163 + if (flag == false) {
163 164 return AjaxResult.error("新增物料失败,存入数据库时报错");
164 165 }
165 166 return AjaxResult.success("新增物料成功");
... ... @@ -202,7 +203,7 @@ public class MaterialServiceImpl extends ServiceImpl&lt;MaterialMapper, Material&gt; i
202 203 LambdaQueryWrapper<InventoryDetail> detailLambdaQueryWrapper = Wrappers.lambdaQuery();
203 204 detailLambdaQueryWrapper.eq(InventoryDetail::getMaterialCode, code)
204 205 .eq(InventoryDetail::getWarehouseCode, ShiroUtils.getWarehouseCode())
205   - .in(InventoryDetail::getCompanyCode,ShiroUtils.getCompanyCodeList());
  206 + .in(InventoryDetail::getCompanyCode, ShiroUtils.getCompanyCodeList());
206 207 List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(detailLambdaQueryWrapper);
207 208 if (!inventoryDetailList.isEmpty()) {
208 209 for (InventoryDetail inventoryDetail : inventoryDetailList) {
... ... @@ -215,7 +216,7 @@ public class MaterialServiceImpl extends ServiceImpl&lt;MaterialMapper, Material&gt; i
215 216 detailLambdaQueryWrapper = Wrappers.lambdaQuery();
216 217 detailLambdaQueryWrapper.like(InventoryDetail::getMaterialName, code)
217 218 .eq(InventoryDetail::getWarehouseCode, ShiroUtils.getWarehouseCode())
218   - .in(InventoryDetail::getCompanyCode,ShiroUtils.getCompanyCodeList());
  219 + .in(InventoryDetail::getCompanyCode, ShiroUtils.getCompanyCodeList());
219 220 List<InventoryDetail> inventoryDetailList1 = inventoryDetailService.list(detailLambdaQueryWrapper);
220 221 if (!inventoryDetailList1.isEmpty()) {
221 222 for (InventoryDetail inventoryDetail : inventoryDetailList) {
... ... @@ -230,11 +231,10 @@ public class MaterialServiceImpl extends ServiceImpl&lt;MaterialMapper, Material&gt; i
230 231 }
231 232  
232 233  
233   -
234 234 @Override
235 235 public Map<String, MaterialComputeVariableBO> getPhysicalDimensionByCodes(List<String> materialCodeList) {
236 236 LambdaQueryWrapper<Material> meterialWrapper = Wrappers.lambdaQuery();
237   - meterialWrapper.in(Material::getCode,materialCodeList);
  237 + meterialWrapper.in(Material::getCode, materialCodeList);
238 238 List<Material> materialList = this.list(meterialWrapper);
239 239  
240 240 return materialList.stream()
... ... @@ -249,41 +249,88 @@ public class MaterialServiceImpl extends ServiceImpl&lt;MaterialMapper, Material&gt; i
249 249 }
250 250  
251 251 @Override
252   - public QueryWrapper<InventoryTransaction> inventoryTurnoverAnalysis(String type ,String materialCode, String createdBegin, String createdEnd) {
253   - String countSql="SUM(CASE WHEN transactionType = 10 THEN taskQty ELSE 0 END) AS inQty," +
  252 + public QueryWrapper<InventoryTransaction> inventoryTurnoverAnalysis(String type, String materialCode, String createdBegin, String createdEnd) {
  253 + String countSql = "SUM(CASE WHEN transactionType = 10 THEN taskQty ELSE 0 END) AS inQty," +
254 254 "ABS(SUM(CASE WHEN transactionType = 20 THEN taskQty ELSE 0 END)) AS outQty," +
255 255 "SUM(CASE WHEN taskQty > 0 THEN taskQty ELSE 0 END) + ABS(SUM(CASE WHEN taskQty < 0 THEN taskQty ELSE 0 END)) AS taskQty," +
256 256 "materialName,materialSpec,materialUnit\n";
257 257 QueryWrapper<InventoryTransaction> materialQueryWrapper = new QueryWrapper<>();
258 258  
259 259 return materialQueryWrapper
260   - .select(type,countSql)
  260 + .select(type, countSql)
261 261 //物料编码
262 262 .like(StringUtils.isNotEmpty(materialCode), "materialCode", materialCode)
263 263 .in("transactionType", 10, 20)
264 264 // 单独materialCode groupby 与SQL模式only_full_group_by不兼容
265   - .groupBy("materialCode","materialName","materialSpec","materialUnit")
  265 + .groupBy("materialCode", "materialName", "materialSpec", "materialUnit")
266 266 .ge(StringUtils.isNotEmpty(createdBegin), "created", createdBegin)
267 267 .le(StringUtils.isNotEmpty(createdEnd), "created", createdEnd)
268 268 .orderByDesc("taskQty");
269 269 }
270 270  
  271 +
  272 + /*
  273 +
  274 + SELECT
  275 + materialCode,
  276 + SUM( CASE WHEN transactionType = 10 THEN 1 ELSE 0 END ) AS inQty,
  277 + SUM( CASE WHEN transactionType = 20 THEN 1 ELSE 0 END ) AS outQty,
  278 + COUNT(*) AS taskQty,
  279 + materialName,
  280 + materialSpec,
  281 + materialUnit
  282 +FROM
  283 + inventory_transaction
  284 +WHERE
  285 + transactionType IN ( 10, 20 )
  286 +GROUP BY
  287 + materialCode,
  288 + materialName,
  289 + materialSpec,
  290 + materialUnit
  291 +ORDER BY
  292 + taskQty DESC
  293 + LIMIT 0,
  294 + 100;
  295 +
  296 + * */
271 297 @Override
272   - public QueryWrapper<InventoryTransaction> inventoryCreatedAnalysis(String type ,String createdBegin, String createdEnd) {
  298 + public QueryWrapper<InventoryTransaction> statisticsMaterialCodeCount(String type, String materialCode, String createdBegin, String createdEnd) {
  299 + String countSql = "SUM(CASE WHEN transactionType = 10 THEN 1 ELSE 0 END) AS inQty," +
  300 + "SUM(CASE WHEN transactionType = 20 THEN 1 ELSE 0 END) AS outQty," +
  301 + "COUNT(*) AS taskQty," +
  302 + "materialName, materialSpec, materialUnit\n";
  303 + QueryWrapper<InventoryTransaction> materialQueryWrapper = new QueryWrapper<>();
  304 +
  305 + return materialQueryWrapper
  306 + .select(type, countSql)
  307 + // 物料编码
  308 + .like(StringUtils.isNotEmpty(materialCode), "materialCode", materialCode)
  309 + .in("transactionType", 10, 20)
  310 + // 单独 materialCode groupby 与 SQL 模式 only_full_group_by 不兼容
  311 + .groupBy("materialCode", "materialName", "materialSpec", "materialUnit")
  312 + .ge(StringUtils.isNotEmpty(createdBegin), "created", createdBegin)
  313 + .le(StringUtils.isNotEmpty(createdEnd), "created", createdEnd)
  314 + .orderByDesc("taskQty");
  315 + }
  316 +
  317 + @Override
  318 + public QueryWrapper<InventoryTransaction> inventoryCreatedAnalysis(String type, String createdBegin, String createdEnd) {
273 319 QueryWrapper<InventoryTransaction> datequeryWrapper = new QueryWrapper<>();
274 320 return datequeryWrapper.select("DATE(created) as datee, SUM(CASE WHEN transactionType = 10 THEN taskQty ELSE 0 END) AS inQty, ABS(SUM(CASE WHEN transactionType = 20 THEN taskQty ELSE 0 END)) AS outQty, SUM(CASE WHEN taskQty > 0 THEN taskQty ELSE 0 END) + ABS(SUM(CASE WHEN taskQty < 0 THEN taskQty ELSE 0 END)) AS taskQty")
275 321 .in("transactionType", 10, 20)
276   - .between("created",createdBegin,createdEnd)
  322 + .between("created", createdBegin, createdEnd)
277 323 .groupBy("DATE(created)");
278 324  
279 325 }
280 326  
281 327 /**
282 328 * 生成物料编码
  329 + *
283 330 * @param code
284 331 * @return
285 332 */
286   - private String createCode(String code){
  333 + private String createCode(String code) {
287 334 LambdaQueryWrapper<MaterialType> lambda = Wrappers.lambdaQuery();
288 335 lambda.eq(MaterialType::getCode, code);
289 336 MaterialType materialType = materialTypeService.getOne(lambda);
... ...
src/main/java/com/huaheng/pc/config/zone/service/ZoneServiceImpl.java
... ... @@ -117,6 +117,9 @@ public class ZoneServiceImpl extends ServiceImpl&lt;ZoneMapper, Zone&gt; implements Zo
117 117 @Transactional
118 118 @Override
119 119 public int saveZone(Zone zone) {
  120 + if (getOne(new LambdaQueryWrapper<Zone>().eq(Zone::getArea, zone.getArea())) != null) {
  121 + throw new ServiceException(("库区的区域已存在," + zone.getArea()));
  122 + }
120 123 zone.setWarehouseCode(ShiroUtils.getWarehouseCode());
121 124 zone.setCreatedBy(ShiroUtils.getName());
122 125 zone.setLastUpdatedBy(ShiroUtils.getName());
... ...
src/main/java/com/huaheng/pc/inventory/inventoryTransaction/service/InventoryTransactionService.java
... ... @@ -6,7 +6,7 @@ import com.huaheng.pc.inventory.inventoryTransaction.domain.vo.InventoryRankVO;
6 6  
7 7 import java.util.Map;
8 8  
9   -public interface InventoryTransactionService extends IService<InventoryTransaction>{
  9 +public interface InventoryTransactionService extends IService<InventoryTransaction> {
10 10  
11 11 /**
12 12 * 根据cron表达式时间同步排行榜数据
... ... @@ -15,6 +15,7 @@ public interface InventoryTransactionService extends IService&lt;InventoryTransacti
15 15  
16 16 /**
17 17 * 通过rediskey获取物料排行
  18 + *
18 19 * @param key
19 20 * @return
20 21 */
... ...
src/main/java/com/huaheng/pc/inventory/inventoryTransaction/service/InventoryTransactionServiceImpl.java
... ... @@ -7,8 +7,10 @@ import com.huaheng.framework.redis.RedisCache;
7 7 import com.huaheng.pc.config.material.service.MaterialService;
8 8 import com.huaheng.pc.inventory.inventoryTransaction.domain.vo.InventoryRankVO;
9 9 import org.springframework.stereotype.Service;
  10 +
10 11 import javax.annotation.Resource;
11 12 import java.util.ArrayList;
  13 +import java.util.HashMap;
12 14 import java.util.List;
13 15 import java.util.Map;
14 16 import java.util.stream.Collectors;
... ... @@ -17,12 +19,13 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
17 19 import com.huaheng.pc.inventory.inventoryTransaction.domain.InventoryTransaction;
18 20 import com.huaheng.pc.inventory.inventoryTransaction.mapper.InventoryTransactionMapper;
19 21 import com.huaheng.pc.inventory.inventoryTransaction.service.InventoryTransactionService;
20   -@Service
21   -public class InventoryTransactionServiceImpl extends ServiceImpl<InventoryTransactionMapper, InventoryTransaction> implements InventoryTransactionService{
22 22  
  23 +@Service
  24 +public class InventoryTransactionServiceImpl extends ServiceImpl<InventoryTransactionMapper, InventoryTransaction> implements InventoryTransactionService {
23 25  
24   - private final static String INVENTORY_RANKING_KEY = "INVENTORY_RANKING";
25 26  
  27 + private final static String INVENTORY_RANKING_TOP_30_KEY = "INVENTORY_RANKING_TOP_30";
  28 + private final static String INVENTORY_RANKING_TOP_70_KEY = "INVENTORY_RANKING_TOP_70";
26 29 @Resource
27 30 private RedisCache redisCache;
28 31  
... ... @@ -31,15 +34,19 @@ public class InventoryTransactionServiceImpl extends ServiceImpl&lt;InventoryTransa
31 34  
32 35 @Override
33 36 public void taskSyncSave() {
34   - List<Object> rankList = redisCache.getCacheList(INVENTORY_RANKING_KEY);
35   - if(CollectionUtil.isNotEmpty(rankList)){
  37 + List<Object> rankList = redisCache.getCacheList(INVENTORY_RANKING_TOP_30_KEY);
  38 + List<Object> rankList2 = redisCache.getCacheList(INVENTORY_RANKING_TOP_70_KEY);
  39 + if (CollectionUtil.isNotEmpty(rankList) || CollectionUtil.isNotEmpty(rankList2)) {
36 40 // del
37   - redisCache.deleteObject(INVENTORY_RANKING_KEY);
  41 + redisCache.deleteObject(INVENTORY_RANKING_TOP_30_KEY);
  42 + redisCache.deleteObject(INVENTORY_RANKING_TOP_70_KEY);
38 43 // save
39   - this.saveMeterial();
  44 + this.saveMaterial();
  45 + } else {
  46 + // init
  47 + saveMaterial();
40 48 }
41   - // init
42   - saveMeterial();
  49 +
43 50 }
44 51  
45 52  
... ... @@ -48,13 +55,20 @@ public class InventoryTransactionServiceImpl extends ServiceImpl&lt;InventoryTransa
48 55 List<Object> rankList = redisCache.getCacheList(key);
49 56 // key material code
50 57 // value material object
  58 +
  59 + //return rankList.stream()
  60 + // .limit(endIndex - startIndex + 1)// 加1是因为索引是从0开始计数
  61 + // .map(obj -> (InventoryRankVO) obj)
  62 + // .collect(Collectors.toMap(InventoryRankVO::getMaterialCode, vo -> vo));
  63 +
51 64 return rankList.stream()
  65 + //.limit(endIndex - startIndex + 1)
52 66 .map(obj -> (InventoryRankVO) obj)
53   - .collect(Collectors.toMap(InventoryRankVO::getMaterialCode, vo -> vo));
  67 + .collect(Collectors.toMap(InventoryRankVO::getMaterialCode, vo -> vo, (existing, duplicate) -> existing, HashMap::new));
54 68 }
55 69  
56   - private void saveMeterial(){
57   - QueryWrapper<InventoryTransaction> materialQueryWrapper = materialService.inventoryTurnoverAnalysis("materialCode", "", "", "");
  70 + private void saveMaterial() {
  71 + QueryWrapper<InventoryTransaction> materialQueryWrapper = materialService.statisticsMaterialCodeCount("materialCode", "", "", "");
58 72 List<InventoryTransaction> inventoryTransactionList = this.page(new Page<>(0, 30), materialQueryWrapper).getRecords();
59 73 List<InventoryRankVO> rankVOList = new ArrayList<>();
60 74 inventoryTransactionList.forEach(inventory -> {
... ... @@ -68,6 +82,23 @@ public class InventoryTransactionServiceImpl extends ServiceImpl&lt;InventoryTransa
68 82 .materialUnit(inventory.getMaterialUnit())
69 83 .build());
70 84 });
71   - redisCache.setCacheList(INVENTORY_RANKING_KEY, rankVOList);
  85 + redisCache.setCacheList(INVENTORY_RANKING_TOP_30_KEY, rankVOList);
  86 +
  87 +
  88 + //QueryWrapper<InventoryTransaction> materialQueryWrapper2 = materialService.statisticsMaterialCodeCount("materialCode", "", "", "");
  89 + List<InventoryTransaction> inventoryTransactionList2 = this.page(new Page<>(0, 100), materialQueryWrapper).getRecords();
  90 + List<InventoryRankVO> rankVOList2 = new ArrayList<>();
  91 + inventoryTransactionList2.forEach(inventory -> {
  92 + rankVOList2.add(InventoryRankVO.builder()
  93 + .materialCode(inventory.getMaterialCode())
  94 + .inQty(inventory.getInQty())
  95 + .outQty(inventory.getOutQty())
  96 + .taskQty(inventory.getTaskQty())
  97 + .materialName(inventory.getMaterialName())
  98 + .materialSpec(inventory.getMaterialSpec())
  99 + .materialUnit(inventory.getMaterialUnit())
  100 + .build());
  101 + });
  102 + redisCache.setCacheList(INVENTORY_RANKING_TOP_70_KEY, rankVOList2);
72 103 }
73 104 }
... ...
src/main/java/com/huaheng/pc/receipt/receiving/service/ReceivingService.java
... ... @@ -41,6 +41,7 @@ import com.huaheng.pc.task.taskHeader.service.TransferTaskService;
41 41 import org.springframework.stereotype.Service;
42 42 import org.springframework.transaction.annotation.Transactional;
43 43 import com.huaheng.pc.receipt.receiptDetail.service.ReceiptDetailService;
  44 +
44 45 import javax.annotation.Resource;
45 46 import java.util.ArrayList;
46 47 import java.util.List;
... ... @@ -92,10 +93,11 @@ public class ReceivingService {
92 93  
93 94 /**
94 95 * 获取当前单号详情
  96 + *
95 97 * @param receiptCode 入库单号
96 98 * @return 入库单详情
97 99 */
98   - public AjaxResult<List<ReceiptDetail>> scanReceiptCode(String receiptCode) {
  100 + public AjaxResult<List<ReceiptDetail>> scanReceiptCode(String receiptCode) {
99 101 //根据仓库编码和入库单号查询入库单详情
100 102 LambdaQueryWrapper<ReceiptDetail> lambda = new LambdaQueryWrapper<>();
101 103 lambda.eq(ReceiptDetail::getReceiptCode, receiptCode)
... ... @@ -105,7 +107,7 @@ public class ReceivingService {
105 107 return AjaxResult.success(detail);
106 108 }
107 109  
108   - public String filter(List<Location> locationList, List<LocationType> locationTypeList, Container container){
  110 + public String filter(List<Location> locationList, List<LocationType> locationTypeList, Container container) {
109 111 String containerType1 = container.getContainerType();
110 112 LambdaQueryWrapper<ContainerType> containerTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
111 113 containerTypeLambdaQueryWrapper.eq(ContainerType::getCode, containerType1);
... ... @@ -115,30 +117,33 @@ public class ReceivingService {
115 117 String[] locationTypes = locationType.split(",");
116 118 // List<String> codeList = locationTypeList.stream().map(t-> t.getCode()).collect(Collectors.toList());
117 119 List<String> codeList = new ArrayList<>();
118   - for(String type : locationTypes) {
  120 + for (String type : locationTypes) {
119 121 codeList.add(type);
120 122 }
121   - List<Location> newLocation = locationList.stream().filter(t-> codeList.contains(t.getLocationType())).collect(Collectors.toList());
122   - if (newLocation.isEmpty()){
  123 + List<Location> newLocation = locationList.stream().filter(t -> codeList.contains(t.getLocationType())).collect(Collectors.toList());
  124 + if (newLocation.isEmpty()) {
123 125 return null;
124   - } else{
  126 + } else {
125 127 return newLocation.get(0).getCode();
126 128 }
127 129 }
128 130  
129 131 /**
130 132 * 定位
  133 + *
131 134 * @param receiptContainerDetail 入库明细
132 135 * @return
133 136 */
134 137 @Transactional(rollbackFor = Exception.class)
135   - public Boolean position(ReceiptContainerDetail receiptContainerDetail, String area){
  138 + public Boolean position(ReceiptContainerDetail receiptContainerDetail, String area) {
136 139 ReceiptContainerHeader receiptContainerHeader = receiptContainerHeaderService.getById(receiptContainerDetail.getReceiptContainerId());
137   - if (!QuantityConstant.RECEIPT_CONTAINER_BUILD.equals(receiptContainerHeader.getStatus())){
138   - throw new ServiceException(receiptContainerHeader.getContainerCode()+"入库组盘已生成任务不能重新定位");
  140 + if (!QuantityConstant.RECEIPT_CONTAINER_BUILD.equals(receiptContainerHeader.getStatus())) {
  141 + throw new ServiceException(receiptContainerHeader.getContainerCode() + "入库组盘已生成任务不能重新定位");
139 142 }
140 143 //如果入库组盘表中有目标库位说明已经指定
141   - if (StringUtils.isNotEmpty(receiptContainerHeader.getToLocation())){ return true; }
  144 + if (StringUtils.isNotEmpty(receiptContainerHeader.getToLocation())) {
  145 + return true;
  146 + }
142 147 /* 判断入盘容器是否在库位上*/
143 148 Container container = containerService.getContainerByCode(receiptContainerHeader.getContainerCode());
144 149 if (StringUtils.isNotEmpty(container.getLocationCode())) {
... ... @@ -160,8 +165,8 @@ public class ReceivingService {
160 165 Material material = materialService.getMaterialByCode(receiptContainerDetail.getMaterialCode());
161 166 String materialAreaCode = material.getMaterialAreaCode();
162 167 String locationCode = locationAllocationService.allocation(allocationRule, null,
163   - 0, area, null, ShiroUtils.getWarehouseCode(),container.getCode(), materialAreaCode);
164   - if (StringUtils.isNotEmpty(locationCode)){
  168 + 0, area, null, ShiroUtils.getWarehouseCode(), container.getCode(), materialAreaCode, 3);
  169 + if (StringUtils.isNotEmpty(locationCode)) {
165 170 locationService.updateStatus(locationCode, QuantityConstant.STATUS_LOCATION_LOCK);
166 171 } else {
167 172 throw new ServiceException("定位失败,请检查定位规则是否正确");
... ... @@ -173,14 +178,14 @@ public class ReceivingService {
173 178 int rowFlag = location.getRowFlag().intValue();
174 179 Integer preTaskNo = 0;
175 180 //如果是外侧库位,那么就要判断该库位对应的内侧库位是不是有托盘
176   - if(rowFlag == QuantityConstant.ROW_OUT) {
  181 + if (rowFlag == QuantityConstant.ROW_OUT) {
177 182 Location insideLocation = locationService.getInsideNear(location);
178   - if(StringUtils.isNotEmpty(insideLocation.getContainerCode())) {
  183 + if (StringUtils.isNotEmpty(insideLocation.getContainerCode())) {
179 184 Location destinationLocation = locationService.getEmptyLocation(insideLocation);
180 185 AjaxResult ajaxResult = transferTaskService.createTransferTask(insideLocation.getCode(),
181 186 destinationLocation.getCode(), ShiroUtils.getWarehouseCode());
182 187 preTaskNo = (Integer) ajaxResult.getData();
183   - if(ajaxResult.hasErr()) {
  188 + if (ajaxResult.hasErr()) {
184 189 throw new ServiceException("创建移库任务失败");
185 190 }
186 191 // taskHeaderService.sendTaskToWcs(Convert.toIntArray(String.valueOf(preTaskNo)));
... ... @@ -191,7 +196,7 @@ public class ReceivingService {
191 196 //更新库位编码到组盘头表
192 197 receiptContainerHeader.setToLocation(locationCode);
193 198 receiptContainerHeader.setRecvDock("0");
194   - if (!receiptContainerHeaderService.updateById(receiptContainerHeader)){
  199 + if (!receiptContainerHeaderService.updateById(receiptContainerHeader)) {
195 200 throw new ServiceException("更新库位失败");
196 201 }
197 202  
... ... @@ -199,13 +204,17 @@ public class ReceivingService {
199 204 LambdaUpdateWrapper<ReceiptContainerDetail> lambda = Wrappers.lambdaUpdate();
200 205 lambda.eq(ReceiptContainerDetail::getReceiptContainerId, receiptContainerHeader.getId())
201 206 .set(ReceiptContainerDetail::getLocationCode, locationCode);
202   - if (!receiptContainerDetailService.update(lambda)){throw new ServiceException("更新库位编码到入库组盘明细失败");}
  207 + if (!receiptContainerDetailService.update(lambda)) {
  208 + throw new ServiceException("更新库位编码到入库组盘明细失败");
  209 + }
203 210  
204 211 ReceiptDetail oldReceiptDetail = receiptDetailService.getById(receiptContainerDetail.getReceiptDetailId());
205 212 if (!oldReceiptDetail.getProcessStamp().equals("200")) {
206 213 ReceiptDetail receiptDetail = receiptDetailService.queryflow(oldReceiptDetail);
207 214 //更新入库单详情状态
208   - if (!receiptDetailService.updateById(receiptDetail)){ throw new ServiceException("更新入库单详情失败");}
  215 + if (!receiptDetailService.updateById(receiptDetail)) {
  216 + throw new ServiceException("更新入库单详情失败");
  217 + }
209 218 //更新入库单头尾状态
210 219 receiptDetailService.updateReceiptHeaderLastStatus(receiptDetail.getReceiptId());
211 220 }
... ... @@ -215,23 +224,24 @@ public class ReceivingService {
215 224  
216 225 /**
217 226 * 取消定位
  227 + *
218 228 * @param receiptContainerDetail 入库组盘明细
219 229 * @return
220 230 */
221 231 @Transactional(rollbackFor = Exception.class)
222   - public AjaxResult cancelPosition(ReceiptContainerDetail receiptContainerDetail){
  232 + public AjaxResult cancelPosition(ReceiptContainerDetail receiptContainerDetail) {
223 233 //查询入库组盘头
224 234 ReceiptContainerHeader receiptContainerHeader = receiptContainerHeaderService.getById(receiptContainerDetail.getReceiptContainerId());
225   - if (!(receiptContainerHeader.getStatus().shortValue() == QuantityConstant.RECEIPT_CONTAINER_BUILD)){
  235 + if (!(receiptContainerHeader.getStatus().shortValue() == QuantityConstant.RECEIPT_CONTAINER_BUILD)) {
226 236 throw new ServiceException("组盘已生成任务不能取消定位");
227 237 }
228 238 String locationCode = receiptContainerHeader.getToLocation();
229   - if(StringUtils.isEmpty(locationCode)) {
  239 + if (StringUtils.isEmpty(locationCode)) {
230 240 throw new ServiceException("组盘没有定位,不需要取消定位");
231 241 }
232 242 //将入库组盘头表中的而库位编码赋值null
233 243 receiptContainerHeader.setToLocation("");
234   - if (!receiptContainerHeaderService.updateById(receiptContainerHeader)){
  244 + if (!receiptContainerHeaderService.updateById(receiptContainerHeader)) {
235 245 throw new ServiceException("回滚入库组盘头失败");
236 246 }
237 247  
... ... @@ -241,15 +251,15 @@ public class ReceivingService {
241 251 List<ReceiptContainerDetail> receiptContainerDetailList = receiptContainerDetailService.list(lambdaQueryWrapper);
242 252 for (ReceiptContainerDetail receiptContainerDetail2 : receiptContainerDetailList) {
243 253 receiptContainerDetail2.setLocationCode("");
244   - if (!receiptContainerDetailService.updateById(receiptContainerDetail2)){
245   - throw new ServiceException("回滚入库组盘明细失败");
  254 + if (!receiptContainerDetailService.updateById(receiptContainerDetail2)) {
  255 + throw new ServiceException("回滚入库组盘明细失败");
246 256 }
247 257 }
248 258  
249 259 //回滚入库明细状态
250 260 ReceiptDetail receiptDetail = receiptDetailService.getById(receiptContainerDetail.getReceiptDetailId());
251 261 receiptDetail.setProcessStamp(QuantityConstant.RECEIPT_HEADER_POSITION.toString());
252   - if ( !receiptDetailService.updateById(receiptDetail)){
  262 + if (!receiptDetailService.updateById(receiptDetail)) {
253 263 throw new ServiceException("回滚入库明细状态失败");
254 264 }
255 265  
... ... @@ -261,6 +271,7 @@ public class ReceivingService {
261 271  
262 272 /**
263 273 * 查找定位规则
  274 + *
264 275 * @param receiptContainerHeader 入库组盘头
265 276 * @param receiptContainerDetail 入库组盘明细
266 277 * @return
... ... @@ -268,25 +279,25 @@ public class ReceivingService {
268 279 public String findPositionRule(ReceiptContainerHeader receiptContainerHeader, ReceiptContainerDetail receiptContainerDetail) {
269 280 /* 定位规则*/
270 281 String locatingRule = receiptContainerHeader.getLocatingRule();
271   - if (StringUtils.isEmpty(locatingRule)){
  282 + if (StringUtils.isEmpty(locatingRule)) {
272 283 locatingRule = receiptDetailService.getById(receiptContainerDetail.getReceiptDetailId()).getLocatingRule();
273 284 //入库单明细定位规则不为空时执行
274   - if (StringUtils.isEmpty(locatingRule)){
  285 + if (StringUtils.isEmpty(locatingRule)) {
275 286 //入库单明细为空时,查询物料表中是否含有定位规则
276 287 LambdaQueryWrapper<Material> materialLambda = Wrappers.lambdaQuery();
277 288 materialLambda.eq(Material::getCode, receiptContainerDetail.getMaterialCode())
278   - .eq(Material::getWarehouseCode,ShiroUtils.getWarehouseCode());
  289 + .eq(Material::getWarehouseCode, ShiroUtils.getWarehouseCode());
279 290 Material material = materialService.getOne(materialLambda);
280 291 locatingRule = material.getLocatingRule();
281 292  
282   - if (StringUtils.isEmpty(locatingRule)){
  293 + if (StringUtils.isEmpty(locatingRule)) {
283 294 //物料表中定位规则为空时,查询物料类别
284 295 LambdaQueryWrapper<MaterialType> materialTypeLambda = Wrappers.lambdaQuery();
285 296 materialTypeLambda.eq(MaterialType::getCode, material.getType())
286   - .eq(MaterialType::getWarehouseCode,ShiroUtils.getWarehouseCode());
  297 + .eq(MaterialType::getWarehouseCode, ShiroUtils.getWarehouseCode());
287 298 MaterialType materialType = materialTypeService.getOne(materialTypeLambda);
288 299 locatingRule = materialType.getLocatingRule();
289   - if (StringUtils.isEmpty(locatingRule)){
  300 + if (StringUtils.isEmpty(locatingRule)) {
290 301 //物料类别中定位规则为空时,查询入库首选项
291 302 LambdaQueryWrapper<ConfigValue> configValueLambda = Wrappers.lambdaQuery();
292 303 configValueLambda.eq(ConfigValue::getWarehouseCode, ShiroUtils.getWarehouseCode())
... ... @@ -295,7 +306,7 @@ public class ReceivingService {
295 306 ConfigValue configValue = configValueService.getOne(configValueLambda);
296 307 LambdaQueryWrapper<ReceiptPreference> lambdaQueryWrapper = Wrappers.lambdaQuery();
297 308 lambdaQueryWrapper.eq(ReceiptPreference::getCode, configValue.getValue())
298   - .eq(ReceiptPreference::getWarehouseCode,ShiroUtils.getWarehouseCode());
  309 + .eq(ReceiptPreference::getWarehouseCode, ShiroUtils.getWarehouseCode());
299 310 locatingRule = preferenceService.getOne(lambdaQueryWrapper).getLocationRule();
300 311 }
301 312 }
... ...
src/main/resources/templates/config/location/location.html
... ... @@ -63,11 +63,27 @@
63 63 <!--名称:<input type="text" name="name"/>-->
64 64 <!--</li>-->
65 65 <li>
  66 + 内外侧:<select id="rowFlag" name="rowFlag">
  67 + <option value="-1">所有</option>
  68 + <option value="0">内侧</option>
  69 + <option value="1">外侧</option>
  70 + </select>
  71 + </li>
  72 + <li>
66 73 库位是否有容器:<select id="userDef2" name="userDef2">
67 74 <option value="">所有</option>
68 75 <option value="有容器">有容器</option>
69 76 <option value="没有容器">没有容器</option>
70 77 </select>
  78 + </li>
  79 + <li>
  80 + 库位常用分区:<select id="frequencyLocation" name="frequencyLocation">
  81 + <option value="-1">所有</option>
  82 + <option value="1">A-频繁使用</option>
  83 + <option value="2">B-常用库位</option>
  84 + <option value="3">C-不常用库位</option>
  85 + </select>
  86 + </li>
71 87 <li class="time2">
72 88 <label>创建时间: </label>
73 89 <input type="text" class="time-input" id="startTime" placeholder="开始时间"
... ... @@ -109,6 +125,9 @@
109 125 shiro:hasPermission="config:location:remove"><!--权限判断shiro是否有User用户字段remove-->
110 126 <i class="fa fa-trash-o"></i> 删除
111 127 </a>
  128 + <a class="btn btn-outline btn-success btn-rounded" onclick="SelectFrequencyLocation()">
  129 + <i class="fa fa-edit"></i> 批量选择常用库位
  130 + </a>
112 131 </div>
113 132  
114 133 <div class="col-sm-12 select-info">
... ... @@ -230,6 +249,24 @@
230 249 }
231 250 },
232 251 {
  252 + field: 'frequencyLocation',
  253 + title: '库位常用分区',
  254 + visible: true,
  255 + align: 'center',
  256 + formatter: function (value, row, index) {
  257 + if (value != undefined) {
  258 + if (value == 3) {
  259 + return '<span style="color:black">不常用库位</span>'
  260 + } else if (value == 2) {
  261 + return '<span style="color:green">常用库位</span>'
  262 + } else if (value == 1) {
  263 + return '<span style="color:#b90e0e">频繁使用</span>'
  264 + }
  265 + }
  266 + return '';
  267 + }
  268 + },
  269 + {
233 270 field: 'materialAreaCode',
234 271 title: '物料分区'
235 272 },
... ... @@ -312,6 +349,16 @@
312 349 }
313 350 }
314 351  
  352 + function SelectFrequencyLocation() {
  353 + let rows = $.table.selectColumns("id");
  354 + if (rows.length == 0) {
  355 + $.modal.alertWarning("请至少选择一条记录");
  356 + return;
  357 + } else {
  358 + $.modal.open("选择类别", prefix + "/selectFrequencyLocation/" + rows.join(","));
  359 + }
  360 + }
  361 +
315 362 /* function print() {
316 363 var rows=$("#bootstrap-table").bootstrapTable('getSelections'); // 获取id = bootstrap-table行
317 364 if (rows.length == 0) {
... ...
src/main/resources/templates/config/location/selectFrequencyLocation.html 0 → 100644
  1 +<!DOCTYPE HTML>
  2 +<html lang="zh" xmlns:th="http://www.thymeleaf.org">
  3 +<meta charset="utf-8">
  4 +<head th:include="include :: header"></head>
  5 +<body class="white-bg">
  6 +<div class="wrapper wrapper-content animated fadeInRight ibox-content">
  7 + <form class="form-horizontal m" id="form-material-edit">
  8 + <input name="ids" hidden="hidden" th:value="${ids}">
  9 + <div class="form-group">
  10 + <label class="col-sm-3 control-label">库位常用类别:</label>
  11 + <div class="col-sm-8">
  12 + <select id="type" name="type" class="form-control">
  13 + <option value="1">A-频繁使用</option>
  14 + <option value="2">B-常用库位</option>
  15 + <option value="3">C-不常用库位</option>
  16 + </select>
  17 + </div>
  18 + </div>
  19 + <div class="form-group">
  20 + <div class="form-control-static col-sm-offset-9">
  21 + <button type="submit" class="btn btn-primary">提交</button>
  22 + <button onclick="$.modal.close()" class="btn btn-danger" type="button">关闭</button>
  23 + </div>
  24 + </div>
  25 + </form>
  26 +</div>
  27 +<div th:include="include::footer"></div>
  28 +<script type="text/javascript">
  29 + var prefix = ctx + "config/location";
  30 + // $("#form-material-edit").validate({
  31 + // submitHandler: function (form) {
  32 + // var tableValue = $("#form-material-add").serialize();
  33 + // $.operate.save(prefix + "/editSelectTypeSave", tableValue);
  34 + // }
  35 + // });
  36 + $("#form-material-edit").validate({
  37 + submitHandler: function (form) {
  38 + $.ajax({
  39 + cache: true,
  40 + type: "POST",
  41 + url: prefix + "/selectFrequencyLocation",
  42 + data: {
  43 + "ids": $("input[name='ids']").val(),
  44 + "type": $("#type option:selected").val(),
  45 + },
  46 + async: false,
  47 + error: function (request) {
  48 + $.modal.alertError("请求失败!");
  49 + },
  50 + success: function (data) {
  51 + $.operate.saveSuccess(data);
  52 + }
  53 + });
  54 + }
  55 + });
  56 +</script>
  57 +</body>
  58 +</html>
... ...
src/test/java/com.huaheng.test/Demo.java
... ... @@ -82,7 +82,7 @@ public class Demo {
82 82 .list(new LambdaQueryWrapper<Location>()
83 83 .eq(Location::getZoneCode, "A"));
84 84 // .eq(Location::getStatus, LocationStatus.));
85   - if(CollectionUtil.isNotEmpty(locationList)){
  85 + if (CollectionUtil.isNotEmpty(locationList)) {
86 86 LinkedList<Location> locationLinkedList = new LinkedList<>(locationList);
87 87 locationLinkedList.sort(Comparator.comparingInt(Location::getId));
88 88 Location nearestLocation = locationLinkedList.pollFirst();
... ...