no message

main
HUOJIN\92525 2024-07-31 17:21:20 +08:00
parent a83c86d3b9
commit 60c35db239
24 changed files with 371 additions and 459 deletions

View File

@ -12,6 +12,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ -117,22 +118,18 @@ public class BydAppController {
return successResponse("出场成功!");
}
@PostMapping("/callAssemblyLine")
@Log("装配线叫料")
@ApiOperation("装配线叫料")
@PostMapping("/operationFeedback")
@Log("任务放行")
@ApiOperation("任务放行")
@AnonymousAccess
public ResponseEntity<Object> callAssemblyLine(@RequestBody CallAssemblyLine callAssemblyLine) {
public ResponseEntity<Object> operationFeedback(@RequestBody ContainerIn containerIn) {
try {
String orderNo = callAssemblyLine.getOrderNo();//工单号
String itemCode = callAssemblyLine.getItemCode();//物料编号
String workStation = callAssemblyLine.getWorkStation();//需求工位
String pointCode = callAssemblyLine.getPointCode();//需求点位;
String containerCode = containerIn.getContainerCode();
stockService.operationFeedback(containerCode);
return successResponse("放行成功!");
} catch (Exception e) {
return badRequest(e.getMessage());
}
return successResponse("入库成功!");
}

View File

@ -79,15 +79,15 @@ public class Point extends BaseEntity implements Serializable {
private Dept dept;
@Column(name = "`pos_x`")
@ApiModelProperty(value = "坐标X")
@ApiModelProperty(value = "")
private Double posX = 0d;
@Column(name = "`pos_y`")
@ApiModelProperty(value = "坐标Y")
@ApiModelProperty(value = "")
private Double posY = 0d;
@Column(name = "`pos_z`")
@ApiModelProperty(value = "坐标Z")
@ApiModelProperty(value = "")
private Double posZ = 0d;
@Column(name = "`type`")

View File

@ -18,11 +18,20 @@ package com.youchain.basicdata.repository;
import com.youchain.basicdata.domain.Area;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
import java.util.Set;
/**
* @website https://eladmin.vip
* @author HJL
* @website https://eladmin.vip
* @date 2023-08-14
**/
public interface AreaRepository extends JpaRepository<Area, Long>, JpaSpecificationExecutor<Area> {
@Query(" from Area a where a.code = :code and a.enabled = true ")
Area findByCode(String code);
@Query(" from Area a where a.code in :areaCodes and a.enabled = true ")
List<Area> findByCodes(Set areaCodes);
}

View File

@ -23,13 +23,13 @@ import com.youchain.annotation.AnonymousAccess;
import com.youchain.annotation.Log;
import com.youchain.appupdate.inputJson.CurrentPage;
import com.youchain.basicdata.domain.Area;
import com.youchain.basicdata.domain.Item;
import com.youchain.basicdata.domain.Point;
import com.youchain.basicdata.service.AreaService;
import com.youchain.basicdata.service.PointService;
import com.youchain.basicdata.service.dto.AreaDto;
import com.youchain.basicdata.service.dto.PointQueryCriteria;
import com.youchain.config.FileProperties;
import com.youchain.config.thread.ThreadPoolExecutorUtil;
import com.youchain.exception.handler.ApiResult;
import com.youchain.modules.system.domain.Dept;
import com.youchain.utils.*;
@ -48,8 +48,7 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
@ -101,24 +100,41 @@ public class PointController {
List<Map<String, Object>> readAll = reader.readAll();
try {
Set<String> pointCodes = new HashSet<>();//点位集合
Set<String> areaCodes = new HashSet<>();//库区集合
for (Map<String, Object> record : readAll) {
String pointCode = record.get("编码").toString().trim();
String areaCode = record.get("库区").toString().trim();
if (!StringUtils.isEmpty(pointCode)) {
pointCodes.add(pointCode);
}
if (!StringUtils.isEmpty(areaCode)) {
areaCodes.add(areaCode);
}
}
//获取已存在的点位
Map<String, Point> existingPoint = pointService.findByCodes(pointCodes);
//查找数据库中存在的库区
List<Area> areaList = areaService.findByCodes(areaCodes);
Set<String> newAreaCodes = areaList.stream().map(Area::getCode).collect(Collectors.toSet());
// 取areaCodes和newAreaCodes的差集说明有不存在的库区
Set<String> diffItemCodes = areaCodes.stream().filter(code -> !newAreaCodes.contains(code)).collect(Collectors.toSet());
if (!diffItemCodes.isEmpty()) {
throw new IllegalArgumentException("WMS不存在的库区集合,请维护:" + diffItemCodes);
}
Map<String, Area> existingArea = areaList.stream().collect(Collectors.toMap(Area::getCode, Area -> Area));
List<Point> pointsToCreate = new ArrayList<>();//新增点位集合
List<Point> pointsToUpdate = new ArrayList<>();//修改点位集合
for (Map<String, Object> record : readAll) {
String pointCode = record.get("编码").toString().trim();
String areaCode = record.get("库区").toString().trim();
Area area = redisObjectUtils.getObjectFromCache(areaCode, () -> areaService.findByCode(areaCode), areaCode + " 系统无此库区!");
Area area = existingArea.get(areaCode);
//判断是否已存在点位
if (existingPoint.containsKey(pointCode)) {
Point point = existingPoint.get(pointCode);
@ -130,24 +146,15 @@ public class PointController {
}
}
//异步处理
ExecutorService executor = ThreadPoolExecutorUtil.getPoll("point-import-job");
CompletableFuture<Void> createFuture = CompletableFuture.runAsync(() -> {
//批量新增Mo票
if (!pointsToCreate.isEmpty()) {
batchCreateOrUpdate.batchCreate(pointsToCreate);
batchCreateOrUpdate.batchInsert(pointsToCreate);
}
}, executor);
CompletableFuture<Void> updateFuture = CompletableFuture.runAsync(() -> {
//批量更新Mo票
if (!pointsToUpdate.isEmpty()) {
batchCreateOrUpdate.batchUpdate(pointsToUpdate);
}
}, executor);
// 等待所有操作完成
CompletableFuture.allOf(createFuture, updateFuture).join();
executor.shutdown();//关闭线程池
return successRequest("导入成功:" + " 新增(" + pointsToCreate.size() + ")修改(" + pointsToUpdate.size() + ")", "");
} catch (Exception e) {
return badRequest("导入失败:" + e.getMessage());

View File

@ -41,8 +41,6 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import javax.servlet.http.HttpServletResponse;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
@ -74,6 +72,7 @@ public class StockController {
public void exportStock(HttpServletResponse response, StockQueryCriteria criteria) throws IOException {
stockService.download(stockService.queryAll(criteria), response);
}
@Log("容器导入")
@ApiOperation("容器导入")
@PostMapping(value = "/import_stock")
@ -113,23 +112,15 @@ public class StockController {
stocksToCreate.add(createStock(stockType, UserUtils.getDept(), record));
}
}
ExecutorService executor = ThreadPoolExecutorUtil.getPoll("stock-import-job");
CompletableFuture<Void> createFuture = CompletableFuture.runAsync(() -> {
//批量新增Mo票
if (!stocksToCreate.isEmpty()) {
batchCreateOrUpdate.batchCreate(stocksToCreate);
batchCreateOrUpdate.batchInsert(stocksToCreate);
}
}, executor);
CompletableFuture<Void> updateFuture = CompletableFuture.runAsync(() -> {
//批量更新Mo票
if (!stocksToUpdate.isEmpty()) {
batchCreateOrUpdate.batchUpdate(stocksToUpdate);
}
}, executor);
// 等待所有操作完成
CompletableFuture.allOf(createFuture, updateFuture).join();
executor.shutdown();//关闭线程池
return successRequest("导入成功:" + " 新增(" + stocksToCreate.size() + ")修改(" + stocksToUpdate.size() + ")", "");
} catch (Exception e) {

View File

@ -22,6 +22,7 @@ import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
/**
@ -61,6 +62,13 @@ public interface AreaService {
*/
Area findByCode(String code);
/**
* code
* @param areaCodes
* @return
*/
List<Area> findByCodes(Set areaCodes);
/**
*
* @param resources /
@ -89,4 +97,6 @@ public interface AreaService {
void download(List<AreaDto> all, HttpServletResponse response) throws IOException;
Area toEntity(AreaDto areaDto);
}

View File

@ -153,25 +153,15 @@ public interface StockService {
void containerOut(String containerCode);
/**
*
*
*
* @param itemCode
* @param pointCode
* @param scene
* @param Code
*/
void callContainer(String itemCode, String pointCode, int scene);
void operationFeedback(String Code);
Map<String, Stock> findByCodes(Set stockCodes);
/**
* Mo
*
* @param mo
* @param stockCode
* @return
*/
String scanMo(String stockCode, String mo);
/**
*
*

View File

@ -30,19 +30,17 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.io.IOException;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
/**
* @author HJL
* @website https://eladmin.vip
* @description
* @author HJL
* @date 2023-08-14
**/
@Service
@ -125,12 +123,11 @@ public class AreaServiceImpl implements AreaService {
@Override
public Area findByCode(String code) {
String hql="select t from Area t where t.code='"+code+"' or t.name='"+code+"' ";
Query query=entityMapper.createQuery(hql);
List<Area> ts=query.getResultList();
if(ts.size()>0){
return ts.get(0);
return areaRepository.findByCode(code);
}
return null;
@Override
public List<Area> findByCodes(Set areaCodes) {
return areaRepository.findByCodes(areaCodes);
}
}

View File

@ -36,8 +36,6 @@ import org.springframework.data.domain.Pageable;
import java.io.File;
import java.util.*;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.http.HttpServletResponse;
@ -225,24 +223,15 @@ public class ItemServiceImpl implements ItemService {
}
}
//异步处理
ExecutorService executor = ThreadPoolExecutorUtil.getPoll("item-import-job");
CompletableFuture<Void> createFuture = CompletableFuture.runAsync(() -> {
//批量新增物料
if (!itemsToCreate.isEmpty()) {
batchCreateOrUpdate.batchCreate(itemsToCreate);
batchCreateOrUpdate.batchInsert(itemsToCreate);
}
}, executor);
CompletableFuture<Void> updateFuture = CompletableFuture.runAsync(() -> {
//批量更新物料
if (!itemsToUpdate.isEmpty()) {
batchCreateOrUpdate.batchUpdate(itemsToUpdate);
}
}, executor);
// 等待所有操作完成
CompletableFuture.allOf(createFuture, updateFuture).join();
executor.shutdown();//关闭线程池
return ("导入成功:" + " 新增(" + itemsToCreate.size() + ")修改(" + itemsToUpdate.size() + ")");
}

View File

@ -48,7 +48,6 @@ public class PointServiceImpl implements PointService {
private final PointRepository pointRepository;
private final PointMapper pointMapper;
private final EntityManager entityMapper;
@Override
public Map<String, Object> queryAll(PointQueryCriteria criteria, Pageable pageable) {

View File

@ -27,13 +27,9 @@ import com.youchain.basicdata.repository.PointRepository;
import com.youchain.basicdata.service.ItemService;
import com.youchain.basicdata.vo.BarCodeVo;
import com.youchain.businessdata.domain.*;
import com.youchain.businessdata.repository.AgvTaskRepository;
import com.youchain.businessdata.repository.InventoryRepository;
import com.youchain.businessdata.repository.PickDetailRepository;
import com.youchain.businessdata.repository.TaskRepository;
import com.youchain.businessdata.repository.*;
import com.youchain.businessdata.service.*;
import com.youchain.businessdata.service.dto.TaskDto;
import com.youchain.config.thread.ThreadPoolExecutorUtil;
import com.youchain.utils.*;
import lombok.RequiredArgsConstructor;
import com.youchain.basicdata.repository.StockRepository;
@ -50,9 +46,8 @@ import org.springframework.data.domain.Pageable;
import java.sql.Timestamp;
import java.util.*;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
@ -75,10 +70,10 @@ public class StockServiceImpl implements StockService {
private final InventoryRepository inventoryRepository;
private final AgvTaskService agvTaskService;
private final ItemService itemService;
private final ItemKeyService itemKeyService;
private final InventoryService inventoryService;
private final InventoryLogService inventoryLogService;
private final AsnDetailService asnDetailService;
private final PickDetailService pickDetailService;
private final TaskService taskService;
private final StockTypeToAreaMap stockTypeToAreaMap;
private final BatchCreateOrUpdate batchCreateOrUpdate;
@ -248,47 +243,10 @@ public class StockServiceImpl implements StockService {
}
@Override
@Transactional(rollbackFor = Exception.class)
public void callContainer(String itemCode, String pointCode, int scene) {
Point endPoint = validateSrcPoint(pointCode);//验证点位
checkPointStatus(endPoint);//验证点位状态
switch (scene) {
case 2: // 叫满车
handleFullContainerCall(itemCode, endPoint);
break;
default:
throw new RuntimeException("无效的业务场景!");
}
public void operationFeedback(String Code) {
}
@Override
@Transactional(rollbackFor = Exception.class)
public String scanMo(String stockCode, String mo) {
/* Map<String, String> map = parseString(mo);//解析二维码
String propC1 = map.get("Lot");//批次号
String boxNumber = map.get("S");//箱号
String propC3 = map.get("P");//工厂
String propD1 = map.get("D");//生产日期
double orderQty = Double.parseDouble(getStringCode(map.get("Q")));//数量
if (asnDetailService.existsByboxNumber(boxNumber)) {
throw new RuntimeException(boxNumber + "箱号已入库,请勿重复操作!");
}
Item item = validateItem(getStringCode(map.get("M")));//验证物料
Stock stock = validateStock(stockCode);//验证容器
validateStockStatus(stock, item);//验证容器物料是否一致
validateStockAndItem(stock, item);//验证容器类型和物料类型是否匹配
//容器类型:小件入库则入小件缓存区、大件入库则入大件缓存区
if (!stockTypeToAreaMap.getStockTypeToAreaMap().containsKey(stock.getStockType())) {
throw new RuntimeException(stock.getStockType() + "容器类型错误!");
}
AsnDetail asnDetail = asnDetailService.createAsnDetail(item, stock, null, propC1, boxNumber, propC3, Timestamp.valueOf(DateUtil.formatDateTime(DateUtil.parse(propD1))), orderQty, mo);
ItemKey itemKey = itemKeyService.getItemKey(item, asnDetail.getPropC1(), asnDetail.getOrderNumber());//生成Itemkey
createTask(item, itemKey, asnDetail, stock, null, null, null);//生成Task任务
stock.setStatus(BaseStatus.USED);
update(stock);
return boxNumber;*/
return "";
}
@Override
@Transactional(rollbackFor = Exception.class)
@ -305,18 +263,11 @@ public class StockServiceImpl implements StockService {
/**验证箱条码集合是否为同一物料,箱号是否重复*/
validateItemCodeAndOrderNumber(barCodeVos);
/**验证箱号是否已入库*/
for (BarCodeVo barCodeVo : barCodeVos) {
if (asnDetailService.existsByboxNumber(barCodeVo.getBoxNumber())) {
throw new RuntimeException(barCodeVo.getBoxNumber() + "箱号已入库,请勿重复操作!");
}
}
/**验证物料*/
String firstItemCode = barCodeVos.iterator().next().getItemCode();
Item item = validateItem(firstItemCode);
/*容器类型:小件入库则入小件缓存区、大件入库则入大件缓存区*/
/*容器类型:托盘*/
validateStockType(stock.getStockType());
/**验证起点点位*/
@ -342,6 +293,8 @@ public class StockServiceImpl implements StockService {
/**更新库存和点位状态*/
updateStockAndPoints(stock, srcPoint, endPoint);
agvTaskService.sendAgvTaskCCImpl(agvTask);//发送任务
}
@ -387,6 +340,14 @@ public class StockServiceImpl implements StockService {
if (allUnique) {
throw new RuntimeException("箱号不能重复!");
}
Set<String> barNumbers = barCodeVos.stream().map(BarCodeVo::getBoxNumber).collect(Collectors.toSet());
List<AsnDetail> asnDetails = asnDetailService.existsByboxNumber(barNumbers);
if (!asnDetails.isEmpty()) {
Set<String> newBarNumbers = asnDetails.stream().map(AsnDetail::getOrderNumber).collect(Collectors.toSet());
throw new RuntimeException("箱号已入库,请勿重复入库:" + newBarNumbers);
}
}
private void validateStockType(String stockType) {
@ -403,67 +364,31 @@ public class StockServiceImpl implements StockService {
}
private AgvTask createAndSendAgvTask(Stock stock, Point srcPoint, Point endPoint) {
AgvTask agvTask = new AgvTask(BizStatus.ASN, stock.getCode(), srcPoint.getCode(), endPoint.getCode(), BizStatus.OPEN, "RACK_MOVE");
/*String resultJson = HttpPostUtil.sendPostReq(UrlApi.submitMission(), agvTaskService.sendAgvTaskImplJson(agvTask));
if (StringUtils.isEmpty(resultJson)) {
throw new RuntimeException("AGV返回信息:下发任务接口调用失败!");
}
JSONObject resulObject = JSON.parseObject(resultJson);
if (resulObject == null) {
throw new RuntimeException("AGV返回信息:下发任务接口返回为空!");
}
String code = resulObject.getString("code");
String message = resulObject.getString("message");*/
String code = "0";
String message = "";
if (!"0".equals(code)) {
throw new RuntimeException("AGV返回信息:" + message);
}
AgvTask agvTask = new AgvTask(BizStatus.ASN, stock.getCode(), srcPoint.getCode(), endPoint.getCode(), BizStatus.OPEN, "FORKLIFT_MOVE");
agvTaskService.create(agvTask);
return agvTask;
}
public void createAsnDetailsAndItemKeysAndTasks(List<BarCodeVo> barCodeVos, Item item, Stock stock, Point srcPoint, Point endPoint, AgvTask agvTask) {
ExecutorService executor = ThreadPoolExecutorUtil.getPoll("materialIn-job");
try {
List<AsnDetail> createAsnDetails = new ArrayList<>();
List<ItemKey> createItemKeys = new ArrayList<>();
List<Task> createAsnTasks = new ArrayList<>();
for (BarCodeVo barCodeVo : barCodeVos) {
AsnDetail asnDetail = createAsnDetail(item, stock, srcPoint, barCodeVo.getPropC1(), barCodeVo.getBoxNumber(), barCodeVo.getPropC3(), Timestamp.valueOf(DateUtil.formatDateTime(DateUtil.parse(barCodeVo.getPropD1()))), barCodeVo.getOrderQty(), barCodeVo.getMo());
createAsnDetails.add(asnDetail);
ItemKey itemKey = createItemKey(item, barCodeVo.getPropC1(), barCodeVo.getBoxNumber());
createItemKeys.add(itemKey);
ItemKey itemKey = itemKeyService.getItemKey(item, barCodeVo.getPropC1(), barCodeVo.getBoxNumber());
Task task = createAsnTask(item, itemKey, asnDetail, stock, srcPoint, endPoint, agvTask);
createAsnTasks.add(task);
}
CompletableFuture<Void> asnDetailFuture = CompletableFuture.runAsync(() -> {
if (!createAsnDetails.isEmpty()) {
batchCreateOrUpdate.batchCreate(createAsnDetails);
batchCreateOrUpdate.batchInsert(createAsnDetails);
}
}, executor);
CompletableFuture<Void> itemKeyFuture = asnDetailFuture.thenRunAsync(() -> {
if (!createItemKeys.isEmpty()) {
batchCreateOrUpdate.batchCreate(createItemKeys);
}
}, executor);
CompletableFuture<Void> taskFuture = itemKeyFuture.thenRunAsync(() -> {
if (!createAsnTasks.isEmpty()) {
batchCreateOrUpdate.batchCreate(createAsnTasks);
batchCreateOrUpdate.batchInsert(createAsnTasks);
}
}, executor);
taskFuture.join();
} catch (Exception e) {
throw new RuntimeException("创建任务失败!", e);
} finally {
executor.shutdown();
}
}
@ -485,6 +410,7 @@ public class StockServiceImpl implements StockService {
}
private ItemKey createItemKey(Item item, String propC1, String orderNumber) {
ItemKey newItemKey = new ItemKey();
newItemKey.setItem(item);
newItemKey.setDept(item.getDept());
@ -515,16 +441,6 @@ public class StockServiceImpl implements StockService {
return task;
}
private void validateStockAndItem(Stock stock, Item item) {
if (item.getGoodType().contains("大件") || item.getGoodType().contains("小件")) {
if (!item.getGoodType().substring(0, 2).equals(stock.getStockType().substring(0, 2))) {
throw new RuntimeException("物料类型和容器类型不匹配!");
}
}
}
private Map<String, String> parseString(String QRCode) {
//P:工厂;V:客户编号;M:物料编号/PCS;B:BYD批次;Lot:供应商批次号;S:工单编号;PO:采购订单/箱号;Q:数量;D:生产日期;YX:有效天数;
// 使用分号分隔字符串
@ -616,7 +532,7 @@ public class StockServiceImpl implements StockService {
Point endPoint = endPointList.get(0);
AgvTask agvTask = new AgvTask(BizStatus.Cp_Off_Line, stock.getCode(), srcPoint.getCode(), endPoint.getCode(), BizStatus.OPEN, "RACK_MOVE");
agvTaskService.create(agvTask);
agvTaskService.sendAgvTaskImpl(agvTask);
agvTaskService.sendAgvTaskHJImpl(agvTask);
endPoint.setStatus(BaseStatus.USED);
pointRepository.save(endPoint);
stock.setStatus(BaseStatus.USED);
@ -651,8 +567,8 @@ public class StockServiceImpl implements StockService {
List<AgvTask> agvTaskList = agvTaskRepository.findRepeat(emptyStock.getCode());
if (agvTaskList.isEmpty()) {
AgvTask agvTask = new AgvTask(BizStatus.EMPTY_IN, emptyStock.getCode(), srcPoint.getCode(), endPoint.getCode(), BizStatus.OPEN, "RACK_MOVE");
agvTaskService.create(agvTask);
agvTaskService.sendAgvTaskImpl(agvTask);
agvTaskRepository.save(agvTask);
agvTaskService.sendAgvTaskHJImpl(agvTask);
// 更新点位状态
endPoint.setStatus(BaseStatus.USED);
@ -778,9 +694,9 @@ public class StockServiceImpl implements StockService {
}
Point endPoint = endPointList.get(0);
AgvTask agvTask = new AgvTask(BizStatus.FB_RETURN, stock.getCode(), srcPoint.getCode(), endPoint.getCode(), BizStatus.OPEN, "");
AgvTask agvTask = new AgvTask(BizStatus.FB_RETURN, stock.getCode(), srcPoint.getCode(), endPoint.getCode(), BizStatus.OPEN, "FORKLIFT_MOVE");
agvTaskService.create(agvTask);
agvTaskService.sendAgvTaskImpl(agvTask);
agvTaskService.sendAgvTaskCCImpl(agvTask);
}
private Item validateItem(String itemCode) {
@ -831,10 +747,6 @@ public class StockServiceImpl implements StockService {
}
}
private void sendAgvTaskAndHandleResponse(AgvTask agvTask) {
agvTaskService.sendAgvTaskImpl(agvTask);
}
private void updateStockAndPoints(Stock stock, Point srcPoint, Point endPoint) {
stock.setStatus(BaseStatus.USED);
@ -848,36 +760,6 @@ public class StockServiceImpl implements StockService {
pointRepository.save(srcPoint);
}
private void handleFullContainerCall(String itemCode, Point endPoint) {
Item item = validateItem(itemCode);//验证物料
String endPointAreaCode = endPoint.getArea().getCode();
//只允许叫料区叫满车
if (!isValidMCJLArea(endPointAreaCode)) {
throw new RuntimeException(endPoint.getCode() + "点位不能叫满车!");
}
List<Inventory> inventoryList = inventoryService.findByItemIdAndAreaCode(item.getId(), item.getGoodType());
if (inventoryList.isEmpty()) {
throw new RuntimeException(itemCode + "物料无库存,呼叫失败!");
}
PickDetail pickDetail = pickDetailService.createPickDetail(item, "");
try {
pickDetailService.allocateAll(pickDetail.getId(), endPoint, item.getGoodType());
List<Task> taskList = taskService.findByPickNotAllTask(pickDetail.getId());
AgvTask agvTask = taskList.get(0).getAgvTask();
sendAgvTaskAndHandleResponse(agvTask);
endPoint.setStatus(BaseStatus.USED);
pointRepository.save(endPoint);
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
private boolean isValidMCJLArea(String areaCode) {
return AreaNameDic.JLQ.equals(areaCode);
}
/**
* AGV
@ -923,7 +805,7 @@ public class StockServiceImpl implements StockService {
pointRepository.save(point);
stock.setStatus(BaseStatus.FREE);
stock.setPoint(point);
update(stock);
stockRepository.save(stock);
}
}

View File

@ -33,9 +33,9 @@ public interface AsnDetailRepository extends JpaRepository<AsnDetail, Long>, Jpa
@Query(value = " from AsnDetail ad WHERE ad.stock.code =:code and ad.status=:status ")
AsnDetail findByStock(String code, String status);
@Query(value = " from AsnDetail ad WHERE ad.orderNumber =:orderNumber ")
List<AsnDetail> findByOrderNumber(String orderNumber);
@Query(value = " from AsnDetail ad WHERE ad.orderNumber in :orderNumber and ad.status not in('CANCEL') ")
List<AsnDetail> findByOrderNumber(Set orderNumber);
@Query(value = " FROM AsnDetail ad WHERE ad.stock.code =?1 and ad.status not in('RECEIVED') ")
List<AsnDetail> findByStockCode(String stockCode);
/* @Query(value = " FROM AsnDetail ad WHERE ad.stock.code =?1 and ad.status not in('RECEIVED') ")
List<AsnDetail> findByStockCode(String stockCode);*/
}

View File

@ -92,15 +92,21 @@ public interface AgvTaskService {
AgvTask toEntity(AgvTaskDto agvTaskDto);
/**
*
*
* @param agvTasks
* @return
*/
void sendAgvTaskCCImpl(AgvTask agvTasks);
/**
*
*
* @param agvTasks
* @return
*/
String sendAgvTaskImpl(AgvTask agvTasks);
String sendAgvTaskImplJson(AgvTask agvTasks);
void sendAgvTaskHJImpl(AgvTask agvTasks);
/**
*

View File

@ -27,18 +27,20 @@ import java.sql.Timestamp;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
/**
* @author hjl
* @website https://eladmin.vip
* @description
* @author hjl
* @date 2023-08-14
**/
public interface AsnDetailService {
/**
*
*
* @param criteria
* @param pageable
* @return Map<String, Object>
@ -47,6 +49,7 @@ public interface AsnDetailService {
/**
*
*
* @param criteria
* @return List<AsnDetailDto>
*/
@ -54,6 +57,7 @@ public interface AsnDetailService {
/**
* ID
*
* @param id ID
* @return AsnDetailDto
*/
@ -61,6 +65,7 @@ public interface AsnDetailService {
/**
*
*
* @param resources /
* @return AsnDetailDto
*/
@ -68,18 +73,21 @@ public interface AsnDetailService {
/**
*
*
* @param resources /
*/
void update(AsnDetail resources);
/**
*
*
* @param ids /
*/
void deleteAll(Long[] ids);
/**
*
*
* @param all
* @param response /
* @throws IOException /
@ -88,6 +96,7 @@ public interface AsnDetailService {
/**
* dto
*
* @param detailDto
* @return
*/
@ -95,6 +104,7 @@ public interface AsnDetailService {
/**
* code
*
* @param code
* @return
*/
@ -102,6 +112,7 @@ public interface AsnDetailService {
/**
* AsnDetail
*
* @param item
* @return
*/
@ -109,6 +120,7 @@ public interface AsnDetailService {
/**
* AsnDetail
*
* @param item
* @return
*/
@ -116,8 +128,9 @@ public interface AsnDetailService {
/**
* MoAsnDetail
*
* @param boxNumber
* @return
*/
boolean existsByboxNumber(String boxNumber);
List<AsnDetail> existsByboxNumber(Set boxNumber);
}

View File

@ -142,7 +142,7 @@ public class AgvTaskServiceImpl implements AgvTaskService {
* @return
*/
@Override
public synchronized String sendAgvTaskImpl(AgvTask agvTasks) {
public synchronized void sendAgvTaskCCImpl(AgvTask agvTasks) {
JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
@ -152,30 +152,30 @@ public class AgvTaskServiceImpl implements AgvTaskService {
objMap.put("missionCode", agvTasks.getId());//任务编号
objMap.put("missionType", agvTasks.getJobType());//货 架 ( 托 盘 ) 移动 RACK_MOVE
objMap.put("viewBoardType", "");//
objMap.put("robotType", "LIFT");//机器人功能类型
JSONArray robotModels = new JSONArray();
objMap.put("robotModels", robotModels);//机器人具体型号
JSONArray robotIds = new JSONArray();
objMap.put("robotIds", robotIds);//机器人编号
objMap.put("containerCode", agvTasks.getStockCode());//
objMap.put("robotType", "FORKLIFT");//机器人功能类型
objMap.put("priority", "1");//数值越小,优先级越高,默认是 1
objMap.put("containerModelCode", "");//容器模型编码
objMap.put("containerCode", "");//
objMap.put("templateCode", "");//作业流程模板编号
objMap.put("lockRobotAfterFinish", false);//是否需要流程结束后机器人保持任务锁定状态
objMap.put("unlockRobotId", "");//解锁当前小车的在上个任务的锁定状态
objMap.put("unlockMissionCode", "");//当前小车的上一个任务
objMap.put("idleNode", "");//作业流程完成后,指定机器人停放区域/点
JSONArray missionDataArray = new JSONArray();
JSONObject missionDataObj = new JSONObject(new LinkedHashMap<>());
Map<String, Object> missionDataMap = new LinkedHashMap<>();
missionDataMap.put("sequence", 1);//序号
missionDataMap.put("containerCode", agvTasks.getStockCode());//容器编号
missionDataMap.put("startPosition", agvTasks.getStartSlotCode());//起始点
missionDataMap.put("startPositionType", "NODE_POINT");//作业位置类型点位NODE_POINT
missionDataMap.put("endPosition", agvTasks.getEndSlotCode());//目标点
missionDataMap.put("endPositionType", "NODE_POINT");//作业位置类型点位NODE_POINT
missionDataMap.put("position", agvTasks.getStartSlotCode());//点位
missionDataMap.put("nodeType", "NODE_POINT");//
missionDataMap.put("stackNumber", 0);
missionDataMap.put("actionConfirm", false);
missionDataObj.putAll(missionDataMap);
missionDataArray.add(missionDataObj);
JSONObject missionDataObj2 = new JSONObject(new LinkedHashMap<>());
Map<String, Object> missionDataMap2 = new LinkedHashMap<>();
missionDataMap2.put("sequence", 2);//序号
missionDataMap2.put("position", agvTasks.getEndSlotCode());//目标点
missionDataMap2.put("nodeType", "NODE_SLOT");//
missionDataMap2.put("stackNumber", 0);
missionDataMap2.put("actionConfirm", false);
missionDataObj2.putAll(missionDataMap2);
missionDataArray.add(missionDataObj2);
objMap.put("missionData", missionDataArray);
jsonObject.putAll(objMap);
String resultJson = HttpPostUtil.sendPostReq(UrlApi.submitMission(), jsonObject.toString());
@ -200,50 +200,56 @@ public class AgvTaskServiceImpl implements AgvTaskService {
agvTasks.setStartTime(new Timestamp(new Date().getTime()));
update(agvTasks);
}
return resultJson;
}
@Override
public String sendAgvTaskImplJson(AgvTask agvTasks) {
public synchronized void sendAgvTaskHJImpl(AgvTask agvTasks) {
JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
Map<String, Object> objMap = new LinkedHashMap<>();
objMap.put("orgId", agvTasks.getId());//库存组织 ID
objMap.put("requestId", agvTasks.getId());//请求 id
objMap.put("missionCode", agvTasks.getId());//任务编号
objMap.put("missionType", agvTasks.getJobType());//货 架 ( 托 盘 ) 移动 RACK_MOVE
objMap.put("viewBoardType", "");//上视识别类型;需要 IDENTIFY_REQUIRE 不需要NORMAL
objMap.put("viewBoardType", "");//IDENTIFY_REQUIRE
objMap.put("robotType", "LIFT");//机器人功能类型
JSONArray robotModels = new JSONArray();
objMap.put("robotModels", robotModels);//机器人具体型号
JSONArray robotIds = new JSONArray();
objMap.put("robotIds", robotIds);//机器人编号
objMap.put("priority", "1");//数值越小,优先级越高,默认是 1
objMap.put("containerModelCode", "");//容器模型编码
objMap.put("containerCode", "");//容器编号
objMap.put("templateCode", "");//作业流程模板编号
objMap.put("lockRobotAfterFinish", false);//是否需要流程结束后机器人保持任务锁定状态
objMap.put("unlockRobotId", "");//解锁当前小车的在上个任务的锁定状态
objMap.put("unlockMissionCode", "");//当前小车的上一个任务
objMap.put("idleNode", "");//作业流程完成后,指定机器人停放区域/点
JSONArray missionDataArray = new JSONArray();
JSONObject missionDataObj = new JSONObject(new LinkedHashMap<>());
Map<String, Object> missionDataMap = new LinkedHashMap<>();
missionDataMap.put("sequence", 1);//序号
missionDataMap.put("containerCode", agvTasks.getStockCode());//容器编号
missionDataMap.put("startPosition", agvTasks.getStartSlotCode());//起始
missionDataMap.put("startPositionType", "NODE_POINT");//作业位置类型点位NODE_POINT
missionDataMap.put("endPosition", agvTasks.getEndSlotCode());//目标
missionDataMap.put("endPositionType", "NODE_POINT");//作业位置类型点位NODE_POINT
missionDataMap.put("containerCode", agvTasks.getStockCode());//容器
missionDataMap.put("startPosition", agvTasks.getStartSlotCode());//点位
missionDataMap.put("startPositionType", "NODE_POINT");//
missionDataMap.put("endPosition", agvTasks.getEndSlotCode());//
missionDataMap.put("endPositionType", "NODE_POINT");//
missionDataObj.putAll(missionDataMap);
missionDataArray.add(missionDataObj);
objMap.put("missionData", missionDataArray);
jsonObject.putAll(objMap);
return jsonObject.toString();
String resultJson = HttpPostUtil.sendPostReq(UrlApi.submitMission(), jsonObject.toString());
if (StringUtils.isEmpty(resultJson)) {
throw new RuntimeException("AGV返回信息:下发任务接口调用失败!");
}
JSONObject resulObject = JSON.parseObject(resultJson);
if (resulObject == null) {
throw new RuntimeException("AGV返回信息:下发任务接口返回为空!");
}
String code = resulObject.getString("code");
String message = resulObject.getString("message");
if (!"0".equals(code)) {
throw new RuntimeException("AGV返回信息:" + message);
} else {
agvTasks.setJobForce(agvTasks.getId().toString());//任务组
agvTasks.setJobForceAsc((1));
agvTasks.setStatus(BizStatus.ATCALL);
agvTasks.setJobMessage(resultJson);
agvTasks.setReqMessage(jsonObject.toString());
agvTasks.setStartTime(new Timestamp(new Date().getTime()));
update(agvTasks);
}
}
@Override
@ -412,6 +418,7 @@ public class AgvTaskServiceImpl implements AgvTaskService {
case "ARRIVED":
break;
case "UP_CONTAINER":
case "FORK_UP":
handleUpContainer(agvTask, containerCode);//容器顶升
break;
case "COMPLETED":

View File

@ -33,12 +33,9 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import cn.hutool.core.date.DateUtil;
@ -182,11 +179,7 @@ public class AsnDetailServiceImpl implements AsnDetailService {
}
@Override
public boolean existsByboxNumber(String boxNumber) {
List<AsnDetail> asnDetailList = asnDetailRepository.findByOrderNumber(boxNumber);
if (asnDetailList.size() > 0) {
return true;
}
return false;
public List<AsnDetail> existsByboxNumber(Set boxNumber) {
return asnDetailRepository.findByOrderNumber(boxNumber);
}
}

View File

@ -49,7 +49,6 @@ public class ItemKeyServiceImpl implements ItemKeyService {
private final ItemKeyRepository itemKeyRepository;
private final ItemKeyMapper itemKeyMapper;
private final EntityManager entityManager;
@Override
public Map<String, Object> queryAll(ItemKeyQueryCriteria criteria, Pageable pageable) {
@ -128,7 +127,7 @@ public class ItemKeyServiceImpl implements ItemKeyService {
newItemKey.setDept(item.getDept());
newItemKey.setPropC1(propC1);
newItemKey.setOrderNumber(orderNumber);
create(newItemKey);
itemKeyRepository.save(newItemKey);
return newItemKey;
}
}

View File

@ -17,6 +17,7 @@ package com.youchain.businessdata.service.impl;
import com.youchain.RequestData.ItemDate;
import com.youchain.RequestData.Yclbl;
import com.youchain.RequestData.ZcData;
import com.youchain.basicdata.domain.Item;
import com.youchain.basicdata.domain.Point;
import com.youchain.basicdata.repository.ItemRepository;
@ -35,6 +36,8 @@ import com.youchain.businessdata.service.PickService;
import com.youchain.businessdata.service.dto.PickDto;
import com.youchain.businessdata.service.dto.PickQueryCriteria;
import com.youchain.businessdata.service.mapstruct.PickMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
@ -44,7 +47,9 @@ import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@ -56,6 +61,7 @@ import java.util.stream.Collectors;
**/
@Service
@RequiredArgsConstructor
@Slf4j
public class PickServiceImpl implements PickService {
private final PickRepository pickRepository;
@ -173,7 +179,6 @@ public class PickServiceImpl implements PickService {
}
@Override
@Transactional(rollbackFor = Exception.class)
public void materialBL(Yclbl yclbl) {
/** 验证参数有效性 */
@ -189,9 +194,10 @@ public class PickServiceImpl implements PickService {
List<PickDetail> createPickDetails = new ArrayList<>();
AtomicInteger lineNo = new AtomicInteger(1);
/** 遍历成品集合 */
String orderNo = yclbl.getOrderNo();
String taskCode = yclbl.getTaskCode();
/** 遍历成品集合 */
yclbl.getBlzc().forEach(zcData -> {
Pick pick = createPick(orderNo, taskCode, lineNo.getAndIncrement(), zcData.getCompleteCode(), zcData.getStation());
createPicks.add(pick);
@ -211,17 +217,23 @@ public class PickServiceImpl implements PickService {
createPickDetails.add(pickDetail);
});
if (!createPicks.isEmpty()) {
pickRepository.saveAll(createPicks);
/** 批量插入 */
try {
batchCreateOrUpdate.batchInsert(createPicks);
} catch (Exception e) {
throw new RuntimeException("出库单创建失败!", e);
}
if (!createPickDetails.isEmpty()) {
pickDetailRepository.saveAll(createPickDetails);
try {
batchCreateOrUpdate.batchInsert(createPickDetails);
} catch (Exception e) {
throw new RuntimeException("出库单明细创建失败!", e);
}
}
/**
*
*
@ -342,7 +354,7 @@ public class PickServiceImpl implements PickService {
}
task.setAgvTask(agvTask);
taskRepository.save(task);
agvTaskService.sendAgvTaskImpl(agvTask);
agvTaskService.sendAgvTaskCCImpl(agvTask);
}
/*更新出库单状态*/
pick.setStatus(BizStatus.PICKUP);

View File

@ -20,11 +20,13 @@ import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 线
*
* @author https://juejin.im/entry/5abb8f6951882555677e9da2
* @date 2019103115:06:18
*/

View File

@ -15,6 +15,8 @@
*/
package com.youchain.config.thread;
import org.springframework.stereotype.Service;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;

View File

@ -1,50 +1,68 @@
package com.youchain.utils;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
@Component
@Service
public class BatchCreateOrUpdate {
@PersistenceContext
private EntityManager entityManager;
/**
*
*
* @param entities
* @param <T>
*/
@Transactional(rollbackFor = Exception.class)
public <T> void batchCreate(List<T> entities) {
if (entities == null || entities.isEmpty()) {
return;
}
for (T entity : entities) {
entityManager.persist(entity);
}
}
//配置文件中每次批量提交的数量
@Value("${spring.jpa.properties.hibernate.jdbc.batch_size}")
private int batchSize;
/**
*
*
*
* @param entities
* @param <T>
* @param list
* @param <T>
*/
@Transactional(rollbackFor = Exception.class)
public <T> void batchUpdate(List<T> entities) {
if (entities == null || entities.isEmpty()) {
@Transactional
public <T> void batchInsert(List<T> list) {
if (list == null || list.isEmpty()) {
return;
}
for (T entity : entities) {
entityManager.merge(entity);
for (int i = 0; i < list.size(); i++) {
entityManager.persist(list.get(i));
if (i % batchSize == 0) {
entityManager.flush();
entityManager.clear();
}
entityManager.flush();
entityManager.clear();
}
}
/**
*
*
* @param list
* @param <T>
*/
@Transactional
public <T> void batchUpdate(List<T> list) {
if (list == null || list.isEmpty()) {
return;
}
for (int i = 0; i < list.size(); i++) {
entityManager.merge(list.get(i));
if (i % batchSize == 0) {
entityManager.flush();
entityManager.clear();
}
}
entityManager.flush();
entityManager.clear();
}
}

View File

@ -6,8 +6,8 @@ spring:
freemarker:
check-template-location: false
profiles:
#active: prod
active: dev
active: prod
#active: dev
jackson:
time-zone: GMT+8
data:
@ -36,11 +36,11 @@ spring:
redis:
#数据库索引
database: ${REDIS_DB:2}
#host: ${REDIS_HOST:192.168.100.102}
#password: ${REDIS_PWD:123456}
host: ${REDIS_HOST:192.168.100.102}
password: ${REDIS_PWD:123456}
host: ${REDIS_HOST:localhost}
password: ${REDIS_PWD:}
#host: ${REDIS_HOST:localhost}
#password: ${REDIS_PWD:}
port: ${REDIS_PORT:6379}
#连接超时时间
timeout: 5000

View File

@ -65,18 +65,7 @@ public class EladminSystemApplicationTests {
System.out.println("集合中不存在分配成功的信息!");
}
CompletableFuture<Void> asnDetailFuture = CompletableFuture.runAsync(() -> {
System.out.println("新增asnDetail");
});
CompletableFuture<Void> itemKeyFuture = asnDetailFuture.thenRunAsync(() -> {
System.out.println("新增itemKey");
});
CompletableFuture<Void> taskFuture = itemKeyFuture.thenRunAsync(() -> {
System.out.println("新增task");
});
taskFuture.join();
Set<BarCodeVo> barCodeVos = new HashSet<>();