feat(location): 根据托盘号进行分组; 从task表中查询出库入库记录;移库库位逻辑修改

This commit is contained in:
陆一凡 2025-03-07 13:53:38 +08:00
parent 67785e397a
commit 7656e6ab50
22 changed files with 496 additions and 47 deletions

View File

@ -214,9 +214,9 @@ public class JobComponent extends BaseController {
return; return;
} }
Location thisLocation = thisLocations.get(0); // 找出当前库位详细信息 Location thisLocation = thisLocations.get(0); // 找出当前库位详细信息
int depth = thisLocation.getDepth(); int depth = 0;
while (depth > 1) { while (depth < thisLocation.getDepth()-1) {
depth--; depth++;
/* 检查该库位有没有任务,若有则退出函数,若没有则检查有没有库存,若没有库存则继续,若有库存则生成一个移库任务,生成之后退出函数 */ /* 检查该库位有没有任务,若有则退出函数,若没有则检查有没有库存,若没有库存则继续,若有库存则生成一个移库任务,生成之后退出函数 */
Location beforLocationsQuery = new Location(); Location beforLocationsQuery = new Location();
// logger.info("{},{},{},{},{}",thisLocation.getAreaId(),thisLocation.getQueue(),thisLocation.getLine(),thisLocation.getLayer(),depth); // logger.info("{},{},{},{},{}",thisLocation.getAreaId(),thisLocation.getQueue(),thisLocation.getLine(),thisLocation.getLayer(),depth);
@ -243,7 +243,7 @@ public class JobComponent extends BaseController {
return; return;
} }
if(!notCompleteTasks.isEmpty()) { if(!notCompleteTasks.isEmpty()) {
logger.info("存在未完成的任务,退出函数"); logger.info("发送出库任务时存在未完成的任务,退出函数");
return; return;
} }
// 检查是否有库存因为存在空框所以不在库存表中检验 // 检查是否有库存因为存在空框所以不在库存表中检验
@ -268,7 +268,7 @@ public class JobComponent extends BaseController {
emptyLocation.setTunnelId(Integer.parseInt(String.valueOf(thisLocation.getTunnelId()).substring(0,1))); emptyLocation.setTunnelId(Integer.parseInt(String.valueOf(thisLocation.getTunnelId()).substring(0,1)));
emptyLocation.setLayer(thisLocation.getLayer()); emptyLocation.setLayer(thisLocation.getLayer());
emptyLocation.setIsChangeArea(1); emptyLocation.setIsChangeArea(1);
List<Location> emptyLocations = locationMapper.findNearLocations(emptyLocation); List<Location> emptyLocations = locationMapper.findChangeLocation(emptyLocation);
if(emptyLocations == null) { if(emptyLocations == null) {
logger.info("emptyLocations == null"); logger.info("emptyLocations == null");
return; return;
@ -316,10 +316,10 @@ public class JobComponent extends BaseController {
moveTask.setRemark1("带料"); moveTask.setRemark1("带料");
} }
int a = taskService.addTask(moveTask); int a = taskService.addTask(moveTask);
if (a == 1 && depth > 1){ if (a == 1 && depth < thisLocation.getDepth()-1 ){
logger.info("生成移库任务成功,任务号:{}", moveTask.getTaskId()); logger.info("生成移库任务成功,任务号:{},深度为1", moveTask.getTaskId());
continue; continue;
} else if (a == 1 && depth == 1) { } else if (a == 1 && depth == thisLocation.getDepth()-1) {
return; return;
} else { } else {
logger.info("生成移库任务失败,任务号:{}", moveTask.getTaskId()); logger.info("生成移库任务失败,任务号:{}", moveTask.getTaskId());
@ -425,10 +425,10 @@ public class JobComponent extends BaseController {
logger.info("查询任务异常"); logger.info("查询任务异常");
return; return;
} }
// if (!notCompleteTasks.isEmpty()) { if (!notCompleteTasks.isEmpty()) {
// logger.info("存在未完成的任务,退出函数"); logger.info("发送移库任务时存在未完成的任务,退出函数");
// return; return;
// } }
} }
logger.info("开始发送移库任务给WCS任务号{}", task.getTaskId()); logger.info("开始发送移库任务给WCS任务号{}", task.getTaskId());
String uuid = UUID.randomUUID().toString(); String uuid = UUID.randomUUID().toString();

View File

@ -197,7 +197,6 @@ public class TaskOperation {
}else{ }else{
log.info("四向车入库完成更新料箱监控成功,任务:{}", task.toLoggerString()); log.info("四向车入库完成更新料箱监控成功,任务:{}", task.toLoggerString());
} }
taskRecordMapper.addTask(task);
} }
return true; return true;
} }
@ -395,7 +394,6 @@ public class TaskOperation {
int updateStock = stockMapper.deleteStockWithLocationId(task.getOrigin()); int updateStock = stockMapper.deleteStockWithLocationId(task.getOrigin());
if(updateStock > 0){ if(updateStock > 0){
log.info("出库完成删除库存成功,任务:{}", task.toLoggerString()); log.info("出库完成删除库存成功,任务:{}", task.toLoggerString());
taskRecordMapper.addTask(task);
return true; return true;
}else{ }else{
log.error("出库完成删除库存失败,任务:{}", task.toLoggerString()); log.error("出库完成删除库存失败,任务:{}", task.toLoggerString());
@ -417,7 +415,6 @@ public class TaskOperation {
int bd = vehicleMapper.deleteVehicle(ab); int bd = vehicleMapper.deleteVehicle(ab);
if (bd == 0){ if (bd == 0){
log.error("四向车空托出库完成更新料箱监控失败,任务:{},原因:更新载具为空状态失败", task.toLoggerString()); log.error("四向车空托出库完成更新料箱监控失败,任务:{},原因:更新载具为空状态失败", task.toLoggerString());
taskRecordMapper.addTask(task);
return false; return false;
}else{ }else{
log.info("四向车空托出库完成更新料箱监控成功,任务:{}", task.toLoggerString()); log.info("四向车空托出库完成更新料箱监控成功,任务:{}", task.toLoggerString());
@ -633,14 +630,12 @@ public class TaskOperation {
int updatedLocation = stockMapper.updateLocationAndStatus(task.getOrigin(), task.getDestination(), StockStatus.OK.getCode()); int updatedLocation = stockMapper.updateLocationAndStatus(task.getOrigin(), task.getDestination(), StockStatus.OK.getCode());
if(updatedLocation > 0){ if(updatedLocation > 0){
log.info("移库库位更新成功,任务:{}", task.toLoggerString()); log.info("移库库位更新成功,任务:{}", task.toLoggerString());
taskRecordMapper.addTask(task);
return true; return true;
}else { }else {
log.info("移库库位更新失败,任务:{}", task.toLoggerString()); log.info("移库库位更新失败,任务:{}", task.toLoggerString());
} }
} else if (Objects.equals(checkUse, "空框")) { } else if (Objects.equals(checkUse, "空框")) {
log.info("空框移库库位更新成功"); log.info("空框移库库位更新成功");
taskRecordMapper.addTask(task);
return true; return true;
} }
// 更新库位 // 更新库位

View File

@ -74,6 +74,9 @@ public class OrderOutController {
return orderOutService.createOrderOut(request); return orderOutService.createOrderOut(request);
} }
@PostMapping(value = "/addOrderByInsertEmpty") @PostMapping(value = "/addOrderByInsertEmpty")
public WmsApiResponse<Object> InsertEmpty(@RequestBody handOrderOutRequest request) { public WmsApiResponse<Object> InsertEmpty(@RequestBody handOrderOutRequest request) {
if (orderOutService.createEmptyLocation(request)){ if (orderOutService.createEmptyLocation(request)){

View File

@ -9,6 +9,7 @@ import com.wms.entity.page.TableRequest;
import com.wms.entity.page.TableResponse; import com.wms.entity.page.TableResponse;
import com.wms.entity.table.Task; import com.wms.entity.table.Task;
import com.wms.service.TaskRecordService; import com.wms.service.TaskRecordService;
import com.wms.service.TaskService;
import com.wms.utils.HttpUtils; import com.wms.utils.HttpUtils;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -35,7 +36,7 @@ public class RecordController extends BaseController {
/** /**
* 任务记录服务 * 任务记录服务
*/ */
private final TaskRecordService taskRecordService; private final TaskService taskService;
/** /**
* 请求头部信息 * 请求头部信息
*/ */
@ -78,7 +79,7 @@ public class RecordController extends BaseController {
taskRecordQuery.setGoodsId(tableRequest.getParam().getGoodsId()); taskRecordQuery.setGoodsId(tableRequest.getParam().getGoodsId());
taskRecordQuery.setVehicleNo(tableRequest.getParam().getVehicleNo()); taskRecordQuery.setVehicleNo(tableRequest.getParam().getVehicleNo());
PageHelper.startPage(pageRequest.getPageNum(), pageRequest.getPageSize(), orderByStr); PageHelper.startPage(pageRequest.getPageNum(), pageRequest.getPageSize(), orderByStr);
List<Task> records = taskRecordService.selTasks(taskRecordQuery); List<Task> records = taskService.selTaskList(taskRecordQuery);
PageInfo<Task> taskRecordPageInfo = new PageInfo<>(records); PageInfo<Task> taskRecordPageInfo = new PageInfo<>(records);
tblResp.setCode(ResponseCode.OK.getCode()); tblResp.setCode(ResponseCode.OK.getCode());
tblResp.setMessage("查询任务记录成功!"); tblResp.setMessage("查询任务记录成功!");

View File

@ -14,6 +14,7 @@ import com.wms.entity.table.Goods;
import com.wms.entity.table.Location; import com.wms.entity.table.Location;
import com.wms.entity.table.PartInfo; import com.wms.entity.table.PartInfo;
import com.wms.entity.table.Stock; import com.wms.entity.table.Stock;
import com.wms.entity.vo.StockVO;
import com.wms.mapper.LocationMapper; import com.wms.mapper.LocationMapper;
import com.wms.mapper.StockMapper; import com.wms.mapper.StockMapper;
import com.wms.service.StockService; import com.wms.service.StockService;
@ -22,6 +23,7 @@ import com.wms.utils.StringUtils;
import com.wms.utils.WmsUtils; import com.wms.utils.WmsUtils;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Isolation;
@ -31,10 +33,8 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.Arrays; import java.util.*;
import java.util.Collections; import java.util.stream.Collectors;
import java.util.Date;
import java.util.List;
/** /**
* WMS库存控制类 * WMS库存控制类
@ -90,9 +90,29 @@ public class StockController extends BaseController {
List<Stock> stocks = stockService.selStocksFront(tableRequest.getParam()); List<Stock> stocks = stockService.selStocksFront(tableRequest.getParam());
PageInfo<Stock> stockPageInfo = new PageInfo<>(stocks); PageInfo<Stock> stockPageInfo = new PageInfo<>(stocks);
tblResp.setCode(ResponseCode.OK.getCode()); tblResp.setCode(ResponseCode.OK.getCode());
// todo 分页之后 获取分组的信息不完整需重新调整
//按照托盘号进行分组
Map<String, List<Stock>> resultMap = stockPageInfo.getList().stream().collect((Collectors.groupingBy(Stock::getVehicleId)));
List<StockVO> stockVOList = new ArrayList<>();
for (Map.Entry<String, List<Stock>> entry : resultMap.entrySet()) {
List<Stock> stockList = entry.getValue();
List<Stock> childrenList = new ArrayList<>();
for (int i = 1; i < stockList.size(); i++) {
childrenList.add(stockList.get(i));
}
StockVO stockVO = new StockVO();
BeanUtils.copyProperties(stockList.get(0), stockVO);
if (stockList.size() > 1) {
stockVO.setChildren(childrenList);
}
stockVOList.add(stockVO);
}
tblResp.setMessage("查询库存成功!"); tblResp.setMessage("查询库存成功!");
tblResp.setRows(stockPageInfo.getList()); tblResp.setRows(stockPageInfo.getList());
tblResp.setTotal(stockPageInfo.getTotal()); tblResp.setTotal(stockService.selGroupByCount(tableRequest.getParam()).size());
logger.info("查询库存成功,总数:{},当前页:{},当前页数量:{}", stockPageInfo.getTotal(), stockPageInfo.getPageNum(), stockPageInfo.getPageSize()); logger.info("查询库存成功,总数:{},当前页:{},当前页数量:{}", stockPageInfo.getTotal(), stockPageInfo.getPageNum(), stockPageInfo.getPageSize());
return JSON.toJSONString(tblResp); return JSON.toJSONString(tblResp);
} }
@ -116,6 +136,24 @@ public class StockController extends BaseController {
} }
/**
* 根据时间查找所有库存
*/
@PostMapping("/getStockByTime")
@ResponseBody
public String getStockByTime(@RequestBody String query){
logger.info("请求的ip地址{}", HttpUtils.getIpAddr(servletRequest));
logger.info("获取所有库存列表");
List<Stock> stocks = stockService.selStocksFront(query);
Map<String, List<Stock>> resultMap = stocks.stream().collect((Collectors.groupingBy(Stock::getVehicleId)));
// 创建响应信息
ResponseEntity rsp = new ResponseEntity();
rsp.setMessage("查询所有库存信息成功");
rsp.setCode(ResponseCode.OK.getCode());
rsp.setReturnData(resultMap);
return JSON.toJSONString(rsp);
}
/** /**
* 根据库位号查询库存 * 根据库位号查询库存
*/ */

View File

@ -1288,7 +1288,7 @@ public class TaskController extends BaseController {
taskQuery.setPickStand(stands.get(0).getStandId()); taskQuery.setPickStand(stands.get(0).getStandId());
} }
PageHelper.startPage(pageRequest.getPageNum(), pageRequest.getPageSize(), orderByStr); PageHelper.startPage(pageRequest.getPageNum(), pageRequest.getPageSize(), orderByStr);
List<Task> tasks = taskService.selTaskByCreateTime(taskQuery); List<Task> tasks = taskService.selTaskList(taskQuery);
PageInfo<Task> taskPageInfo = new PageInfo<>(tasks); PageInfo<Task> taskPageInfo = new PageInfo<>(tasks);
tblResp.setCode(ResponseCode.OK.getCode()); tblResp.setCode(ResponseCode.OK.getCode());
tblResp.setMessage("查询任务成功!"); tblResp.setMessage("查询任务成功!");

View File

@ -0,0 +1,170 @@
package com.wms.entity.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.wms.entity.table.Stock;
import com.wms.utils.excel.ExcelExport;
import lombok.Data;
import org.apache.poi.poifs.property.Child;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.util.List;
/**
* @Classname StockVO
* @Date 2025-03-05 22:16
* @Created by luyifan
*/
@Data
public class StockVO {
/**
* 库存编号
*/
@ExcelExport("库存编号")
private String stockId;
/**
* 库区编号
*/
@ExcelExport("库区编号")
private String warehouseName;
/**
* 库位ID
*/
@ExcelExport("库位")
private String locationId;
/**
* 托盘号
*/
@ExcelExport("箱号")
private String vehicleId;
/**
* 物料编号
*/
@ExcelExport("零件号")
private String goodsId;
/**
* 物料名称
*/
@ExcelExport("零件名称")
private String goodsName;
/**
* 批次号
*/
@ExcelExport("批次号")
private String batchNo;
/**
* 可用数量
*/
@ExcelExport("可用数量")
private Integer availableNum;
/**
* 剩余数量
*/
@ExcelExport("剩余数量")
private Integer remainNum;
/**
* 实际数量
*/
@ExcelExport("实际数量")
private Integer realNum;
/**
* 供应商编号
*/
@ExcelExport("供应商编号")
private String providerId;
/**
* 供应商名称
*/
@ExcelExport("供应商名称")
private String providerName;
/**
* 生产日期
*/
@ExcelExport("生产日期")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date productionDate;
/**
* 过期日期
*/
@ExcelExport("过期日期")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date expirationDate;
/**
* 库存状态
* 正常出库中锁定
*/
@ExcelExport("库存状态")
private Integer stockStatus;
/**
* 物料状态
* 合格不合格报废延期
*/
@ExcelExport("零件状态")
private Integer goodsStatus;
/**
* 创建时间
*/
@ExcelExport("入库时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 最后更新时间
*/
@ExcelExport("最后更新时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date lastUpdateTime;
/**
* 最后更新用户
*/
@ExcelExport("上架人")
private String lastUpdateUser;
/**
* 备注
*/
@ExcelExport("备注")
private String remark;
/**
* 是否盘点
*/
@ExcelExport("是否盘点")
private Integer isInventory;
/**
* 盘点任务号 盘点出库和盘点入库同样
*/
@ExcelExport("盘点任务号")
private String inventoryTaskId;
/**
* 当前位置
*/
@ExcelExport("当前位置")
private String currentLocation;
/**
* 保质期
*/
@ExcelExport("保质期")
private Double shelfLife;
@ExcelExport("单重")
private Double singleWeight;
private List<Stock> children;
}

View File

@ -20,7 +20,7 @@ public interface LocationMapper {
List<Location> selLocations(Location location); List<Location> selLocations(Location location);
List<Location> findNearLocations(Location location); List<Location> findNearLocations(Location location);
List<Location> findChangeLocation(Location location);
List<Location> selSmallDepthLocations(Location location); List<Location> selSmallDepthLocations(Location location);
/** /**

View File

@ -33,6 +33,12 @@ public interface StockMapper {
*/ */
int addStock(Stock stock); int addStock(Stock stock);
/**
* 根据托盘进行分组统计总个数
* @param query
* @return
*/
List<Long> selGroupByCount(@Param("query") String query);
/** /**
* 修改库存信息 * 修改库存信息
* @param stock * @param stock

View File

@ -21,7 +21,7 @@ public interface TaskMapper {
* @return * @return
*/ */
List<Task> selTaskByCreateTime(Task task); List<Task> selTaskByCreateTime(Task task);
List<Task> selTaskList(Task task);
List<Task> selTasksByTaskId(Task task); List<Task> selTasksByTaskId(Task task);
/** /**
* 添加任务 * 添加任务

View File

@ -21,6 +21,7 @@ public interface IOrderOutService {
WmsApiResponse<Object> updateLocation(handOrderOutRequest request); WmsApiResponse<Object> updateLocation(handOrderOutRequest request);
//WmsApiResponse<Object> outRowStock(String rowId); //WmsApiResponse<Object> outRowStock(String rowId);
} }

View File

@ -20,6 +20,8 @@ public interface StockService {
*/ */
List<Stock> selStocksFront(String query); List<Stock> selStocksFront(String query);
List<Long> selGroupByCount(String query);
/** /**
* 添加库存 * 添加库存
* @param stock 库存信息 * @param stock 库存信息

View File

@ -37,4 +37,6 @@ public interface TaskService{
int deleteTask(String taskId); int deleteTask(String taskId);
List<Task> selTaskByCreateTime(Task taskQuery); List<Task> selTaskByCreateTime(Task taskQuery);
List<Task> selTaskList(Task taskQuery);
} }

View File

@ -17,6 +17,7 @@ import org.springframework.stereotype.Service;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
@Service @Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired)) @RequiredArgsConstructor(onConstructor = @__(@Autowired))
@ -80,7 +81,6 @@ public class OrderOutImplements implements IOrderOutService {
// 计算出库 // 计算出库
List<Task> outTasks = new ArrayList<>(); // 出库任务列表 List<Task> outTasks = new ArrayList<>(); // 出库任务列表
/* 查询库存 */ /* 查询库存 */
if(Objects.equals(orderOut.getRemark(), "手动出库")){ if(Objects.equals(orderOut.getRemark(), "手动出库")){
// 拉出该物料的所有正常库存 // 拉出该物料的所有正常库存
Stock queryStock = new Stock(); Stock queryStock = new Stock();
@ -103,6 +103,98 @@ public class OrderOutImplements implements IOrderOutService {
if(availableNum.compareTo(needNum) < 0) { if(availableNum.compareTo(needNum) < 0) {
return new WmsApiResponse<>(1, String.format("该物料库存不足,物料号:%s库存数量%d出库数量%s", orderOut.getGoodsId(), availableNum, orderOut.getGoodsNum()), null); return new WmsApiResponse<>(1, String.format("该物料库存不足,物料号:%s库存数量%d出库数量%s", orderOut.getGoodsId(), availableNum, orderOut.getGoodsNum()), null);
} }
//选择最优库存
// Boolean isMultiVehicle= true;
// for (Stock stock : stockList) {
// if (stock.getAvailableNum() >= needNum) {
// isMultiVehicle = false;
// }
// }
// if (isMultiVehicle) {
// // 生成多托盘出库任务
// List<Stock> sortStockList = stockList.stream().sorted(Comparator.comparingInt(Stock::getAvailableNum).reversed()).collect(Collectors.toList());
// for(Stock outStock : sortStockList) {
// if(needNum <= 0) {
// break;
// }
// // 生成出库任务更新库存为出库中
// int outNum = needNum > outStock.getAvailableNum() ? outStock.getAvailableNum() : needNum; // 需要操作的数量
// if(outTasks.stream().filter(task -> task.getOrigin().equals(outStock.getLocationId())).toList().isEmpty()) {
// Task task = new Task();
// task.setTaskId(String.valueOf(Calendar.getInstance().getTimeInMillis()));
// task.setTaskType(2);
// task.setTaskGroup(orderOut.getOrderId());
// task.setTaskStatus(OrderOutStatusEnum.CREATED.getCode());
// task.setOrigin(outStock.getLocationId());
// task.setDestination("111");
// task.setPickStand(orderOut.getRowId());
// task.setWeight(0.0);
// task.setVehicleNo(outStock.getVehicleId());
// task.setCreateTime(new Date());
// task.setUserName("WMS");
// task.setGoodsId(outStock.getGoodsId());
// task.setGoodsName(outStock.getGoodsName());
// task.setOperateNum(outNum);
// task.setTotalNum(outStock.getRealNum());
// task.setTaskPriority(1);
// task.setRemark1("手动出库");
// outTasks.add(task);
// taskRecordMapper.addTask(task);
// }
// // 把这条库存记录可用数量更新为 0
// stockMapper.updateStockAvailableNumWithStockId(outStock.getStockId(), outStock.getAvailableNum()-outNum);
// // 更新库存为出库中
// stockMapper.updateStockStatusWithLocationId(outStock.getLocationId(), StockStatus.OUT.getCode());
// // 重新计算需求数量
// needNum -= outNum;
// }
// }else{
// // 生成单托盘出库任务
// List<Stock> sortStockList = stockList.stream().sorted(Comparator.comparingInt(Stock::getAvailableNum)).collect(Collectors.toList());
// ArrayList satisfyStockList = new ArrayList<>();
// for (Stock stock : sortStockList) {
// if (stock.getAvailableNum() >= needNum){
// satisfyStockList.add(stock);
// break;
// }
// }
// for(Stock outStock : sortStockList) {
// if(needNum <= 0) {
// break;
// }
// // 生成出库任务更新库存为出库中
// int outNum = needNum > outStock.getAvailableNum() ? outStock.getAvailableNum() : needNum; // 需要操作的数量
// if(outTasks.stream().filter(task -> task.getOrigin().equals(outStock.getLocationId())).toList().isEmpty()) {
// Task task = new Task();
// task.setTaskId(String.valueOf(Calendar.getInstance().getTimeInMillis()));
// task.setTaskType(2);
// task.setTaskGroup(orderOut.getOrderId());
// task.setTaskStatus(OrderOutStatusEnum.CREATED.getCode());
// task.setOrigin(outStock.getLocationId());
// task.setDestination("111");
// task.setPickStand(orderOut.getRowId());
// task.setWeight(0.0);
// task.setVehicleNo(outStock.getVehicleId());
// task.setCreateTime(new Date());
// task.setUserName("WMS");
// task.setGoodsId(outStock.getGoodsId());
// task.setGoodsName(outStock.getGoodsName());
// task.setOperateNum(outNum);
// task.setTotalNum(outStock.getRealNum());
// task.setTaskPriority(1);
// task.setRemark1("手动出库");
// outTasks.add(task);
// taskRecordMapper.addTask(task);
// }
// // 把这条库存记录可用数量更新为 0
// stockMapper.updateStockAvailableNumWithStockId(outStock.getStockId(), outStock.getAvailableNum()-outNum);
// // 更新库存为出库中
// stockMapper.updateStockStatusWithLocationId(outStock.getLocationId(), StockStatus.OUT.getCode());
// // 重新计算需求数量
// needNum -= outNum;
// }
// }
// 手动出库的生成出库任务 // 手动出库的生成出库任务
for(Stock outStock : stockList) { for(Stock outStock : stockList) {
if(needNum <= 0) { if(needNum <= 0) {
@ -130,7 +222,6 @@ public class OrderOutImplements implements IOrderOutService {
task.setTaskPriority(1); task.setTaskPriority(1);
task.setRemark1("手动出库"); task.setRemark1("手动出库");
outTasks.add(task); outTasks.add(task);
taskRecordMapper.addTask(task);
} }
// 把这条库存记录可用数量更新为 0 // 把这条库存记录可用数量更新为 0
stockMapper.updateStockAvailableNumWithStockId(outStock.getStockId(), outStock.getAvailableNum()-outNum); stockMapper.updateStockAvailableNumWithStockId(outStock.getStockId(), outStock.getAvailableNum()-outNum);

View File

@ -25,6 +25,10 @@ public class StockServiceImplements implements StockService {
return stockMapper.selStocksFront(query); return stockMapper.selStocksFront(query);
} }
@Override
public List<Long> selGroupByCount(String query) {
return stockMapper.selGroupByCount(query);
}
@Override @Override
public int addStock(Stock stock) { public int addStock(Stock stock) {
return this.stockMapper.addStock(stock); return this.stockMapper.addStock(stock);

View File

@ -47,4 +47,9 @@ public class TaskServiceImplements implements TaskService {
public List<Task> selTaskByCreateTime(Task taskQuery) { public List<Task> selTaskByCreateTime(Task taskQuery) {
return taskMapper.selTaskByCreateTime(taskQuery); return taskMapper.selTaskByCreateTime(taskQuery);
} }
@Override
public List<Task> selTaskList(Task taskQuery) {
return taskMapper.selTaskList(taskQuery);
}
} }

View File

@ -157,7 +157,6 @@ public class ContainerImplement implements ContainerService {
location.setVehicleId(virtualPalletId); location.setVehicleId(virtualPalletId);
locationMapper.modifyLocation(location); locationMapper.modifyLocation(location);
taskRecordMapper.addTask(newInTask);
success.setCode("200"); success.setCode("200");
success.setMessage("生成入库任务成功"); success.setMessage("生成入库任务成功");
success.setWmsTaskId(newInTask.getTaskId()); success.setWmsTaskId(newInTask.getTaskId());
@ -188,7 +187,7 @@ public class ContainerImplement implements ContainerService {
canUseLocations = canUseLocations.stream().filter(l -> l.getLayer() != 1).toList(); canUseLocations = canUseLocations.stream().filter(l -> l.getLayer() != 1).toList();
} }
Location useLocation = locationUtils.checkCanUse(canUseLocations); Location useLocation = locationUtils.checkCanUseAndChange(canUseLocations);
if(useLocation == null) { if(useLocation == null) {
return new CreateInstoreTaskResponse("400", "暂没有可以直接使用的库位,因为存在互锁的库位,请等待当前任务都执行完成后再试"); return new CreateInstoreTaskResponse("400", "暂没有可以直接使用的库位,因为存在互锁的库位,请等待当前任务都执行完成后再试");
} }
@ -315,9 +314,8 @@ public class ContainerImplement implements ContainerService {
for (Vehicle empty : emptyVehicle) { for (Vehicle empty : emptyVehicle) {
// 根据空托盘位置信息查找对应库位信息 // 根据空托盘位置信息查找对应库位信息
Location queryLocation = new Location(); Location queryLocation = new Location();
queryLocation.setLocationId(vehicle.getCurrentLocation()); queryLocation.setLocationId(empty.getCurrentLocation());
queryLocation.setWareArea("D"); queryLocation.setWareArea("D");
queryLocation.setLocationStatus(LocationStatus.OCCUPY.getCode()); queryLocation.setLocationStatus(LocationStatus.OCCUPY.getCode());
Location location = locationMapper.selLocations( queryLocation) Location location = locationMapper.selLocations( queryLocation)
@ -354,7 +352,7 @@ public class ContainerImplement implements ContainerService {
orderOut.setGoodsNum(String.valueOf(1)); orderOut.setGoodsNum(String.valueOf(1));
//Integer.parseInt(row.getQty()) //Integer.parseInt(row.getQty())
orderOut.setUnit(""); orderOut.setUnit("");
orderOut.setStatus(OrderOutStatusEnum.CREATED.getCode()); orderOut.setStatus(OrderOutStatusEnum.RUNNING.getCode());
orderOut.setCreateTime(new Timestamp(System.currentTimeMillis())); orderOut.setCreateTime(new Timestamp(System.currentTimeMillis()));
orderOut.setRemark("空托盘出库"); orderOut.setRemark("空托盘出库");
orderOut.setBatchNo(null); orderOut.setBatchNo(null);
@ -388,16 +386,8 @@ public class ContainerImplement implements ContainerService {
log.info("添加任务失败"); log.info("添加任务失败");
return new CreateFeedPalletTaskResponse("400", "创建入库单失败"); return new CreateFeedPalletTaskResponse("400", "创建入库单失败");
} }
//更改出库单状态为出库中
OrderOut orderOutUpdateStatus = new OrderOut();
orderOutUpdateStatus.setRowId(orderOutRowId);
orderOutUpdateStatus.setStatus(OrderOutStatusEnum.RUNNING.getCode());
int a = orderOutMapper.update(orderOutUpdateStatus);
if (a > 0){
log.info("更新出库单状态成功");
}else {
log.info("更新出库单状态失败");
}
CreateFeedPalletTaskResponse response = new CreateFeedPalletTaskResponse(); CreateFeedPalletTaskResponse response = new CreateFeedPalletTaskResponse();
response.setCode("200"); response.setCode("200");
response.setMessage("成功"); response.setMessage("成功");

View File

@ -5,9 +5,7 @@ import org.hibernate.validator.constraints.Length;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.*;
import java.util.Date;
import java.util.UUID;
/** /**
* WMS工具类 * WMS工具类

View File

@ -1,7 +1,9 @@
package com.wms.utils.storage; package com.wms.utils.storage;
import com.alibaba.fastjson2.JSON;
import com.wms.constants.enums.LocationStatus; import com.wms.constants.enums.LocationStatus;
import com.wms.entity.app.container.CreateInstoreTaskResponse; import com.wms.entity.app.container.CreateInstoreTaskResponse;
import com.wms.entity.app.display.LocationInfo;
import com.wms.entity.table.AppOrderIn; import com.wms.entity.table.AppOrderIn;
import com.wms.entity.table.Location; import com.wms.entity.table.Location;
import com.wms.entity.table.Stock; import com.wms.entity.table.Stock;
@ -12,9 +14,12 @@ import com.wms.mapper.TaskMapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -136,6 +141,8 @@ public class LocationUtils {
if(differentDepthLocations == null) { if(differentDepthLocations == null) {
continue; // 数据库查询失败 continue; // 数据库查询失败
} }
// boolean canUse = false; // 指示当前库位是否可用若可用会置成 true // boolean canUse = false; // 指示当前库位是否可用若可用会置成 true
if(!differentDepthLocations.isEmpty()) { if(!differentDepthLocations.isEmpty()) {
// 存在干涉库位检验其是否有未完成的任务 // 存在干涉库位检验其是否有未完成的任务
@ -163,6 +170,84 @@ public class LocationUtils {
return null; return null;
} }
/**
* 在一堆空闲的库位中寻找一个可用的入库库位 存在交换区域进行里层交换区与可用库位交换
* @param canUseLocations 可用的库位
* @return 可用的库位若没有可用的库位则返回 null
*/
public Location checkCanUseAndChange(List<Location> canUseLocations) {
if(canUseLocations == null || canUseLocations.isEmpty()) {
return null;
}
boolean canUse = true;
for (Location location : canUseLocations) {
// if(location.getDepth() == 1) {
// return location; // 1 深度的不需要检验
// }
/* 校验此位置是否有遮挡 */ /* 如果这位置有库存(可能出现记错导致有库存),或者这位置其他深度(不论深度大小)有任务则不采用此位置 */
/* 1 判断库存 */
Stock checkStock = new Stock();
checkStock.setLocationId(location.getLocationId());
List<Stock> checkResult = stockMapper.selStocks(checkStock);
if(!checkResult.isEmpty()) {
continue; // 库存不为空跳过
}
/* 2 判断同位置不同深度是否有任务 */
// 找出此位置不同深度的库位
Location queryDifferentDepthLocation = new Location();
queryDifferentDepthLocation.setAreaId(location.getAreaId());
queryDifferentDepthLocation.setQueue(location.getQueue());
queryDifferentDepthLocation.setTunnelId(location.getTunnelId());
queryDifferentDepthLocation.setLayer(location.getLayer());
List<Location> differentDepthLocations = locationMapper.selLocations(queryDifferentDepthLocation);
if(differentDepthLocations == null) {
continue; // 数据库查询失败
}
// boolean canUse = false; // 指示当前库位是否可用若可用会置成 true
if(!differentDepthLocations.isEmpty()) {
// 存在干涉库位检验其是否有未完成的任务
for (Location differentDepthLocation : differentDepthLocations) {
// 找出此位置不同深度的库位
Location queryLocationTask = new Location();
queryLocationTask.setLocationId(differentDepthLocation.getLocationId());
List<Task> locationTasks = taskMapper.haveNotCompleteTask(differentDepthLocation.getLocationId());
if(locationTasks == null) {
log.info("检查存在干涉库位失败,数据库异常");
canUse = false;
break; // 数据库查询失败
}
if(!locationTasks.isEmpty()) {
log.info("检查存在干涉库位失败,此位置有未完成的任务,任务位置{}",differentDepthLocation.getLocationId());
canUse = false;
break; // 有任务这个库位不行
}
}
}
if(canUse) {
// 倒序
// 判断是否存在交换区
for (Location differentDepthLocation :differentDepthLocations) {
if (differentDepthLocation.getIsChangeArea() == 1 && differentDepthLocation.getLocationStatus() == 0 && location.getDepth() < differentDepthLocation.getDepth()){
// 交换当前库位和里面交换区
log.info("存在交换区,当前库位{},与{}进行交换", JSON.toJSONString(location),JSON.toJSONString(differentDepthLocation));
Location updateOrginLocation = new Location();
BeanUtils.copyProperties(differentDepthLocation,updateOrginLocation);
updateOrginLocation.setLocationId(location.getLocationId());
locationMapper.modifyLocation(updateOrginLocation);
Location updateChangeLocation = new Location();
BeanUtils.copyProperties(location,updateChangeLocation);
updateChangeLocation.setLocationId(differentDepthLocation.getLocationId());
locationMapper.modifyLocation(updateChangeLocation);
return differentDepthLocation;
}
}
return location;
}
}
return null;
}
} }

View File

@ -45,6 +45,26 @@
order by tunnel_id asc,depth desc, layer asc, line desc order by tunnel_id asc,depth desc, layer asc, line desc
</select> </select>
<select id="findChangeLocation" parameterType="Location" resultMap="LocationMap">
<include refid="selectAll"/>
<where>
<if test="locationId != null and locationId != ''"> and location_id = #{locationId}</if>
<if test="areaId != null"> and area_id = #{areaId}</if>
<if test="tunnelId != null"> and left(tunnel_id,1) = #{tunnelId}</if>
<if test="equipmentId != null"> and equipment_id = #{equipmentId}</if>
<if test="locationType != null"> and location_type = #{locationType}</if>
<if test="queue != null"> and queue = #{queue}</if>
<if test="line != null"> and line = #{line}</if>
<if test="layer != null"> and layer = #{layer}</if>
<if test="depth != null"> and depth = #{depth}</if>
<if test="isLock != null"> and is_lock = #{isLock}</if>
<if test="locationStatus != null"> and location_status = #{locationStatus}</if>
<if test="vehicleId != null and vehicleId != ''"> and vehicle_id = #{vehicleId}</if>
<if test="wareArea != null and wareArea != ''"> and ware_area = #{wareArea}</if>
<if test="isChangeArea != null"> and is_change_area = #{isChangeArea}</if>
</where>
order by depth desc
</select>
<select id="selLocations" parameterType="Location" resultMap="LocationMap"> <select id="selLocations" parameterType="Location" resultMap="LocationMap">
<include refid="selectAll"/> <include refid="selectAll"/>

View File

@ -46,6 +46,15 @@
order by create_time order by create_time
</select> </select>
<select id="selGroupByCount" parameterType="String" resultType="Long">
select count(*) from tbl_app_stock
<where>
<if test="query != null and query != ''"> vehicle_id = #{query} or goods_id like concat('%', #{query}, '%') or goods_name like concat('%', #{query}, '%') or batch_no = #{query} or create_time like concat('%', #{query}, '%') </if>
</where>
GROUP BY vehicle_id
</select>
<select id="selStocksByGoodsId" parameterType="Stock" resultMap="StockMap"> <select id="selStocksByGoodsId" parameterType="Stock" resultMap="StockMap">
select goods_id, goods_name, SUM(real_num) as real_num select goods_id, goods_name, SUM(real_num) as real_num
from tbl_app_stock from tbl_app_stock

View File

@ -94,6 +94,35 @@
</select> </select>
<select id="selTaskList" parameterType="Task" resultMap="TaskMap">
<include refid="selectAll" />
<where>
<if test="taskId != null and taskId != ''"> and task_id = #{taskId}</if>
<if test="taskType != null"> and task_type = #{taskType}</if>
<if test="taskStatus != null"> and task_status = #{taskStatus}</if>
<if test="taskGroup != null and taskGroup != ''"> and task_group = #{taskGroup}</if>
<if test="origin != null and origin != ''"> and origin = #{origin}</if>
<if test="destination != null and destination != ''"> and destination = #{destination}</if>
<if test="pickStand != null and pickStand != ''"> and pick_stand = #{pickStand}</if>
<if test="weight != null"> and weight = #{weight}</if>
<if test="vehicleNo != null and vehicleNo != ''"> and vehicle_no = #{vehicleNo}</if>
<if test="vehicleSize != null"> and vehicle_size = #{vehicleSize}</if>
<if test="createTime != null"> and create_time = #{createTime}</if>
<if test="userName != null and userName != ''"> and user_name = #{userName}</if>
<if test="goodsId != null and goodsId != ''"> and goods_id = #{goodsId}</if>
<if test="goodsName != null and goodsName != ''"> and goods_name = #{goodsName}</if>
<if test="operateNum != null"> and operate_num = #{operateNum}</if>
<if test="totalNum != null"> and total_num = #{totalNum}</if>
<if test="etagLocation != null and etagLocation != ''"> and etag_location = #{etagLocation}</if>
<if test="taskPriority != null"> and task_priority = #{taskPriority}</if>
<if test="productionDate != null"> and production_date = #{productionDate}</if>
<if test="expirationDate != null"> and expiration_date = #{expirationDate}</if>
<if test="kateTaskId != null and kateTaskId != ''"> and kate_task_id = #{kateTaskId}</if>
<if test="remark1 != null and remark1 != ''"> and remark1 = #{remark1}</if>
</where>
order by create_time desc ,task_status desc
</select>
<select id="selTasksByTaskId" parameterType="Task" resultMap="TaskMap"> <select id="selTasksByTaskId" parameterType="Task" resultMap="TaskMap">
<include refid="selectAll" /> <include refid="selectAll" />
<where> <where>